From: jk7744.park Date: Sat, 24 Oct 2015 07:53:01 +0000 (+0900) Subject: tizen 2.4 release X-Git-Tag: accepted/tizen/2.4/mobile/20151029.032510^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fheads%2Faccepted%2Ftizen_2.4_mobile;p=framework%2Fmultimedia%2Flibmm-radio.git tizen 2.4 release --- diff --git a/Makefile.am b/Makefile.am old mode 100644 new mode 100755 index f2066a6..5f07c23 --- a/Makefile.am +++ b/Makefile.am @@ -10,3 +10,13 @@ pkgconfig_DATA = $(pcfiles) EXTRA_DIST = $(pcfiles) +if ENABLE_EMULATOR +else +if ENABLE_SPRD +dist_udevrules_DATA = \ + rules/sprd/96-fm-radio.rules +else +dist_udevrules_DATA = \ + rules/brcm/96-fm-radio.rules +endif +endif diff --git a/configure.ac b/configure.ac index fd555ad..3e84d30 100755 --- a/configure.ac +++ b/configure.ac @@ -9,6 +9,8 @@ AC_CONFIG_HEADER([config.h]) # Checks for programs. AC_PROG_LIBTOOL +m4_pattern_allow([AM_PROG_AR]) +AM_PROG_AR AC_PROG_CC # Checks for libraries. @@ -36,11 +38,11 @@ PKG_CHECK_MODULES(MMCOMMON, mm-common) AC_SUBST(MMCOMMON_CFLAGS) AC_SUBST(MMCOMMON_LIBS) -PKG_CHECK_MODULES(GST, gstreamer-0.10) +PKG_CHECK_MODULES(GST, gstreamer-1.0) AC_SUBST(GST_CFLAGS) AC_SUBST(GST_LIBS) -PKG_CHECK_MODULES(GSTAPP, gstreamer-app-0.10) +PKG_CHECK_MODULES(GSTAPP, gstreamer-app-1.0) AC_SUBST(GSTAPP_CFLAGS) AC_SUBST(GSTAPP_LIBS) @@ -56,6 +58,16 @@ PKG_CHECK_MODULES(MMSOUND, mm-sound) AC_SUBST(MMSOUND_CFLAGS) AC_SUBST(MMSOUND_LIBS) +PKG_CHECK_MODULES(DBUS, dbus-1) +AC_SUBST(DBUS_CFLAGS) +AC_SUBST(DBUS_LIBS) + +PKG_CHECK_MODULES(INIPARSER, iniparser) +AC_SUBST(INIPARSER_CFLAGS) +AC_SUBST(INIPARSER_LIBS) + +PKG_CHECK_MODULES(TTRACE, [ttrace], AC_DEFINE(ENABLE_TTRACE, 1, [ttrace available])); + AC_ARG_ENABLE(emulator, AC_HELP_STRING([--enable-emulator], [using emulator interface]), [ case "${enableval}" in @@ -66,6 +78,36 @@ AC_ARG_ENABLE(emulator, AC_HELP_STRING([--enable-emulator], [using emulator inte ],[ENABLE_EMULATOR=no]) AM_CONDITIONAL(ENABLE_EMULATOR, test "x$ENABLE_EMULATOR" = "xyes") +AC_ARG_ENABLE(broadcom, AC_HELP_STRING([--enable-broadcom], [using broadcom interface]), +[ + case "${enableval}" in + yes) ENABLE_BROADCOM=yes ;; + no) ENABLE_BROADCOM=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-broadcom) ;; + esac + ], + [ENABLE_BROADCOM=no]) +AM_CONDITIONAL(ENABLE_BROADCOM, test "x$ENABLE_BROADCOM" = "xyes") + +AC_ARG_ENABLE(sprd, AC_HELP_STRING([--enable-sprd], [using sprd interface]), +[ + case "${enableval}" in + yes) ENABLE_SPRD=yes ;; + no) ENABLE_SPRD=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-sprd) ;; + esac + ], + [ENABLE_SPRD=no]) +AM_CONDITIONAL(ENABLE_SPRD, test "x$ENABLE_SPRD" = "xyes") + +AC_ARG_WITH( + [udev-rules-dir], + AS_HELP_STRING([--with-udev-rules-dir],[Directory where to install udev rules to (defaults to /usr/lib/udev/rules.d)]), + [udevrulesdir=$withval], [udevrulesdir="/usr/lib/udev/rules.d"]) + +AC_SUBST(udevrulesdir) + + AC_CONFIG_FILES([ Makefile src/Makefile diff --git a/libmm-radio.manifest b/libmm-radio.manifest index a76fdba..4e0fc09 100755 --- a/libmm-radio.manifest +++ b/libmm-radio.manifest @@ -2,4 +2,7 @@ + + + diff --git a/packaging/libmm-radio.spec b/packaging/libmm-radio.spec old mode 100644 new mode 100755 index 612a8ea..4cbd153 --- a/packaging/libmm-radio.spec +++ b/packaging/libmm-radio.spec @@ -1,6 +1,6 @@ Name: libmm-radio Summary: Multimedia Framework Radio Library -Version: 0.2.15 +Version: 0.2.14 Release: 0 Group: System/Libraries License: Apache-2.0 @@ -12,8 +12,11 @@ BuildRequires: pkgconfig(mm-common) BuildRequires: pkgconfig(mm-log) BuildRequires: pkgconfig(mm-session) BuildRequires: pkgconfig(mm-sound) -BuildRequires: pkgconfig(gstreamer-0.10) -BuildRequires: pkgconfig(gstreamer-plugins-base-0.10) +BuildRequires: pkgconfig(gstreamer-1.0) +BuildRequires: pkgconfig(gstreamer-plugins-base-1.0) +BuildRequires: pkgconfig(ttrace) +BuildRequires: pkgconfig(dbus-1) +BuildRequires: pkgconfig(iniparser) %description Description: Multimedia Framework Radio Library @@ -32,11 +35,15 @@ Description: Multimedia Framework Radio Library (DEV) %build ./autogen.sh -CFLAGS=" %{optflags} -Wall -DEXPORT_API=\"__attribute__((visibility(\\\"default\\\")))\" "; export CFLAGS; +CFLAGS=" %{optflags} -Wall -DENABLE_TTRACE -DEXPORT_API=\"__attribute__((visibility(\\\"default\\\")))\" "; export CFLAGS; + %configure \ %ifarch i586 --enable-emulator \ %endif +%if "%{?tizen_target_name}"== "Z300H" +--enable-sprd \ +%endif --disable-static --prefix=%{_prefix} @@ -60,6 +67,9 @@ cp LICENSE.APLv2 %{buildroot}/usr/share/license/%{name} %defattr(-,root,root,-) %{_libdir}/libmmfradio.so.* %{_bindir}/mm_radio_testsuite +%ifarch %{arm} +%{_libdir}/udev/rules.d/96-fm-radio.rules +%endif /usr/share/license/%{name} diff --git a/rules/brcm/96-fm-radio.rules b/rules/brcm/96-fm-radio.rules new file mode 100644 index 0000000..b2b5eaf --- /dev/null +++ b/rules/brcm/96-fm-radio.rules @@ -0,0 +1,21 @@ +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /dev/radio0" +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /sys/devices/virtual/video4linux/radio0/fmrx_band" +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /sys/devices/virtual/video4linux/radio0/fmrx_chl_lvl" +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /sys/devices/virtual/video4linux/radio0/fmrx_comp_scan" +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /sys/devices/virtual/video4linux/radio0/fmrx_deemph_mode" +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /sys/devices/virtual/video4linux/radio0/fmrx_mute_rate" +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /sys/devices/virtual/video4linux/radio0/fmrx_rds_af" +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /sys/devices/virtual/video4linux/radio0/fmrx_rssi_lvl" +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /sys/devices/virtual/video4linux/radio0/fmrx_set_blndmute" +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /sys/devices/virtual/video4linux/radio0/fmrx_snr40" +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /sys/devices/virtual/video4linux/radio0/fmrx_snr_lvl" +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /sys/devices/virtual/video4linux/radio0/fmrx_start_rssi" +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /sys/devices/virtual/video4linux/radio0/fmrx_start_snr" +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /sys/devices/virtual/video4linux/radio0/fmrx_stop_rssi" +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /sys/devices/virtual/video4linux/radio0/fmrx_stop_snr" +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /sys/devices/virtual/video4linux/radio0/fmrx_start_mute" +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /sys/devices/virtual/video4linux/radio0/fmrx_stop_atten" +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /sys/devices/virtual/video4linux/radio0/fmrx_search_abort" +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /sys/devices/virtual/video4linux/radio0/fmrx_curr_snr" +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /sys/devices/virtual/video4linux/radio0/fmrx_cos_th" +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /sys/devices/virtual/video4linux/radio0/fmrx_status" diff --git a/rules/sprd/96-fm-radio.rules b/rules/sprd/96-fm-radio.rules new file mode 100644 index 0000000..6daf891 --- /dev/null +++ b/rules/sprd/96-fm-radio.rules @@ -0,0 +1,8 @@ +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /dev/radio0" +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /sys/class/video4linux/radio0/fmrx_freq_offset" +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /sys/class/video4linux/radio0/fmrx_noise_power" +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /sys/class/video4linux/radio0/fmrx_pilot_power" +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /sys/devices/virtual/video4linux/radio0/fmrx_search_abort" +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /sys/devices/virtual/video4linux/radio0/fmrx_status" +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /sys/devices/virtual/video4linux/radio0/fmrx_rssi_lvl" +SUBSYSTEM=="video4linux", DEVPATH=="/devices/virtual/video4linux/radio[0-9]", RUN+="/usr/bin/chsmack -a device::radio /sys/class/video4linux/radio0/fmrx_start_mute" diff --git a/src/Makefile.am b/src/Makefile.am old mode 100644 new mode 100755 index 91e1a72..0df9c03 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,12 +4,20 @@ includelibmmfradiodir = $(includedir)/mmf includelibmmfradio_HEADERS = include/mm_radio.h libmmfradio_la_SOURCES = mm_radio.c \ - mm_radio_asm.c + mm_radio_asm.c \ + mm_radio_utils.c if ENABLE_EMULATOR libmmfradio_la_SOURCES += mm_radio_priv_emulator.c else -libmmfradio_la_SOURCES += mm_radio_priv.c + +if ENABLE_SPRD +libmmfradio_la_SOURCES += mm_radio_priv_sprd.c +else +#libmmfradio_la_SOURCES += mm_radio_priv.c +libmmfradio_la_SOURCES += mm_radio_priv_brcm.c +endif + endif libmmfradio_la_CFLAGS = -I. -I./include \ @@ -19,8 +27,14 @@ libmmfradio_la_CFLAGS = -I. -I./include \ $(AUDIOSESSIONMGR_CFLAGS) \ $(MMSOUND_CFLAGS) \ $(GST_CFLAGS) \ + $(INIPARSER_CFLAGS) \ $(GSTAPP_CFLAGS) \ - -DMMF_LOG_OWNER=0x200000 -DMMF_DEBUG_PREFIX=\"MM-RADIO\" + -DMMF_LOG_OWNER=0x200000 -DMMF_DEBUG_PREFIX=\"MM-RADIO\" \ + $(TTRACE_CFLAGS) \ + $(DBUS_CFLAGS) +if ENABLE_SPRD +libmmfradio_la_CFLAGS += -DENABLE_SPRD +endif libmmfradio_la_LIBADD = $(GTHREAD_LIBS) \ $(MMCOMMON_LIBS) \ @@ -28,4 +42,7 @@ libmmfradio_la_LIBADD = $(GTHREAD_LIBS) \ $(AUDIOSESSIONMGR_LIBS) \ $(MMSOUND_LIBS) \ $(GST_LIBS) \ - $(GSTAPP_LIBS) + $(INIPARSER_LIBS) \ + $(GSTAPP_LIBS) \ + $(TTRACE_LIBS) \ + $(DBUS_LIBS) \ No newline at end of file diff --git a/src/include/mm_radio.h b/src/include/mm_radio.h index dba7d56..da7ba35 100644 --- a/src/include/mm_radio.h +++ b/src/include/mm_radio.h @@ -27,7 +27,7 @@ #include #ifdef __cplusplus - extern "C" { +extern "C" { #endif /** @@ -38,7 +38,7 @@ This part describes the APIs with respect to play radio */ - + /** * Enumerations of radio state. @@ -49,7 +49,7 @@ typedef enum { MM_RADIO_STATE_PLAYING, /**< Radio is now playing radio */ MM_RADIO_STATE_SCANNING, /**< Radio is now scanning frequency */ MM_RADIO_STATE_NUM, /**< Number of radio states */ -} MMRadioStateType; +}MMRadioStateType; /** * Enumerations of seeking direction. @@ -79,10 +79,31 @@ typedef enum { MM_RADIO_REGION_GROUP_JAPAN, /**< Region Japan group */ } MMRadioRegionType; +#ifdef ENABLE_TTRACE +#include +#define TTRACE_BEGIN(NAME) traceBegin(TTRACE_TAG_VIDEO, NAME) +#define TTRACE_END() traceEnd(TTRACE_TAG_VIDEO) +#define TTRACE_ASYNCBEGIN(NAME, cookie) traceAsyncBegin (TTRACE_TAG_VIDEO, cookie, NAME); +#define TTRACE_ASYNCEND(NAME, cookie) traceAsyncEnd(TTRACE_TAG_VIDEO, cookie, NAME); +#else +#define TTRACE_BEGIN(NAME) +#define TTRACE_END() +#endif + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + + +#define FEATURE_ASM_SUPPORT + /** * This function creates a radio handle. \n - * So, application can make radio instance and initializes it. - * + * So, application can make radio instance and initializes it. + * * * @param hradio [out] Handle of radio. * @@ -92,217 +113,12 @@ typedef enum { * @remark None * @see mm_radio_destroy mm_radio_realize mm_radio_unrealize mm_radio_start mm_radio_stop * @par Example - * @code -#include -#include -#include - -#define RADIO_TEST__(x_test) \ - ret = x_test \ - if ( ! ret ) \ - { \ - printf("PASS : %s -- %s:%d\n", #x_test, __FILE__, __LINE__); \ - } \ - else \ - { \ - printf("FAIL : %s ERR-CODE : %d -- %s:%d\n", #x_test, ret, __FILE__, __LINE__); \ - } - -static MMHandleType g_my_radio = 0; - -int __menu(void) -{ - int menu_item = 0; - - printf("---------------------------------------------------------\n"); - printf("mm-radio rt api test. try now!\n"); - printf("---------------------------------------------------------\n"); - printf("[1] mm_radio_create\n"); - printf("[2] mm_radio_destroy\n"); - printf("[3] mm_radio_realize\n"); - printf("[4] mm_radio_unrealize\n"); - printf("[7] mm_radio_get_state\n"); - printf("[8] mm_radio_start\n"); - printf("[9] mm_radio_stop\n"); - printf("[10] mm_radio_seek\n"); - printf("[11] mm_radio_set_frequency\n"); - printf("[12] mm_radio_get_frequency\n"); - printf("[13] mm_radio_scan_start\n"); - printf("[14] mm_radio_scan_stop\n"); - printf("[0] quit\n"); - printf("---------------------------------------------------------\n"); - printf("choose one : "); - scanf("%d", &menu_item); - - if ( menu_item > 15 ) - menu_item = -1; - - return menu_item; -} - -int __msg_rt_callback(int message, void *pParam, void *user_param) -{ - MMMessageParamType* param = (MMMessageParamType*)pParam; - int ret = 0; - - printf("incomming message : %d\n", message); - - switch(message) - { - case MM_MESSAGE_STATE_CHANGED: - - printf("MM_MESSAGE_STATE_CHANGED: current : %d old : %d\n" - , param->state.current, param->state.previous); - break; - case MM_MESSAGE_RADIO_SCAN_START: - printf("MM_MESSAGE_RADIO_SCAN_START\n"); - break; - case MM_MESSAGE_RADIO_SCAN_INFO: - assert(param); - printf("MM_MESSAGE_RADIO_SCAN_INFO : freq : %d\n", param->radio_scan.frequency); - break; - case MM_MESSAGE_RADIO_SCAN_STOP: - printf("MM_MESSAGE_RADIO_SCAN_STOP\n"); - break; - case MM_MESSAGE_RADIO_SCAN_FINISH: - printf("MM_MESSAGE_RADIO_SCAN_FINISHED\n"); - break; - case MM_MESSAGE_RADIO_SEEK_START: - printf("MM_MESSAGE_RADIO_SEEK_START\n"); - break; - case MM_MESSAGE_RADIO_SEEK_FINISH: - printf("MM_MESSAGE_RADIO_SEEK_FINISHED : freq : %d\n", param->radio_scan.frequency); - break; - default: - printf("ERROR : unknown message received!\n"); - break; - } - - return true; -} - -void __call_api( int choosen ) -{ - int ret = MM_ERROR_NONE; - - switch( choosen ) - { - case 1: - { - RADIO_TEST__( mm_radio_create( &g_my_radio ); ) - RADIO_TEST__( mm_radio_set_message_callback( g_my_radio, __msg_rt_callback, &g_my_radio); ) - } - break; - - case 2: - { - RADIO_TEST__( mm_radio_destroy( g_my_radio ); ) - g_my_radio = 0; - } - break; - - case 3: - { - RADIO_TEST__( mm_radio_realize(g_my_radio ); ) - } - break; - - case 4: - { - RADIO_TEST__( mm_radio_unrealize(g_my_radio ); ) - } - break; - - case 7: - { - MMRadioStateType state = 0; - RADIO_TEST__( mm_radio_get_state(g_my_radio, &state); ) - - printf("state : %d\n", state); - } - break; - - case 8: - { - RADIO_TEST__( mm_radio_start(g_my_radio); ) - } - break; - - case 9: - { - RADIO_TEST__( mm_radio_stop(g_my_radio); ) - } - break; - - case 10: - { - MMRadioSeekDirectionType direction = 0; - printf("input seek direction(0:UP/1:DOWN) : "); - scanf("%d", &direction); - RADIO_TEST__( mm_radio_seek(g_my_radio, direction); ) - } - break; - - case 11: - { - int freq = 0; - printf("input freq : "); - scanf("%d", &freq); - RADIO_TEST__( mm_radio_set_frequency(g_my_radio, freq); ) - } - break; - - case 12: - { - int freq = 0; - RADIO_TEST__( mm_radio_get_frequency(g_my_radio, &freq ); ) - - printf("freq : %d\n", freq); - } - break; - - case 13: - { - RADIO_TEST__( mm_radio_scan_start(g_my_radio); ) - } - break; - - case 14: - { - RADIO_TEST__( mm_radio_scan_stop(g_my_radio); ) - } - break; - - default: - break; - } -} - -int main(int argc, char **argv) -{ - while(1) - { - char key = 0; - int choosen = 0; - - choosen = __menu(); - - if ( choosen == -1) - continue; - - if ( choosen == 0 ) - break; - - __call_api( choosen ); - } -} - * @endcode */ int mm_radio_create(MMHandleType *hradio); /** * This function deletes radio handle. \n - * It closes radio device and releases all resources allocated. + * It closes radio device and releases all resources allocated. * * @param hradio [in] Handle of radio. * @@ -310,213 +126,8 @@ int mm_radio_create(MMHandleType *hradio); * @pre Application can use this API at any state. * @post None * @remark None - * @see mm_radio_create mm_radio_realize mm_radio_unrealize mm_radio_start mm_radio_stop + * @see mm_radio_create mm_radio_realize mm_radio_unrealize mm_radio_start mm_radio_stop * @par Example - * @code -#include -#include -#include - -#define RADIO_TEST__(x_test) \ - ret = x_test \ - if ( ! ret ) \ - { \ - printf("PASS : %s -- %s:%d\n", #x_test, __FILE__, __LINE__); \ - } \ - else \ - { \ - printf("FAIL : %s ERR-CODE : %d -- %s:%d\n", #x_test, ret, __FILE__, __LINE__); \ - } - -static MMHandleType g_my_radio = 0; - -int __menu(void) -{ - int menu_item = 0; - - printf("---------------------------------------------------------\n"); - printf("mm-radio rt api test. try now!\n"); - printf("---------------------------------------------------------\n"); - printf("[1] mm_radio_create\n"); - printf("[2] mm_radio_destroy\n"); - printf("[3] mm_radio_realize\n"); - printf("[4] mm_radio_unrealize\n"); - printf("[7] mm_radio_get_state\n"); - printf("[8] mm_radio_start\n"); - printf("[9] mm_radio_stop\n"); - printf("[10] mm_radio_seek\n"); - printf("[11] mm_radio_set_frequency\n"); - printf("[12] mm_radio_get_frequency\n"); - printf("[13] mm_radio_scan_start\n"); - printf("[14] mm_radio_scan_stop\n"); - printf("[0] quit\n"); - printf("---------------------------------------------------------\n"); - printf("choose one : "); - scanf("%d", &menu_item); - - if ( menu_item > 15 ) - menu_item = -1; - - return menu_item; -} - -int __msg_rt_callback(int message, void *pParam, void *user_param) -{ - MMMessageParamType* param = (MMMessageParamType*)pParam; - int ret = 0; - - printf("incomming message : %d\n", message); - - switch(message) - { - case MM_MESSAGE_STATE_CHANGED: - - printf("MM_MESSAGE_STATE_CHANGED: current : %d old : %d\n" - , param->state.current, param->state.previous); - break; - case MM_MESSAGE_RADIO_SCAN_START: - printf("MM_MESSAGE_RADIO_SCAN_START\n"); - break; - case MM_MESSAGE_RADIO_SCAN_INFO: - assert(param); - printf("MM_MESSAGE_RADIO_SCAN_INFO : freq : %d\n", param->radio_scan.frequency); - break; - case MM_MESSAGE_RADIO_SCAN_STOP: - printf("MM_MESSAGE_RADIO_SCAN_STOP\n"); - break; - case MM_MESSAGE_RADIO_SCAN_FINISH: - printf("MM_MESSAGE_RADIO_SCAN_FINISHED\n"); - break; - case MM_MESSAGE_RADIO_SEEK_START: - printf("MM_MESSAGE_RADIO_SEEK_START\n"); - break; - case MM_MESSAGE_RADIO_SEEK_FINISH: - printf("MM_MESSAGE_RADIO_SEEK_FINISHED : freq : %d\n", param->radio_scan.frequency); - break; - default: - printf("ERROR : unknown message received!\n"); - break; - } - - return true; -} - -void __call_api( int choosen ) -{ - int ret = MM_ERROR_NONE; - - switch( choosen ) - { - case 1: - { - RADIO_TEST__( mm_radio_create( &g_my_radio ); ) - RADIO_TEST__( mm_radio_set_message_callback( g_my_radio, __msg_rt_callback, &g_my_radio); ) - } - break; - - case 2: - { - RADIO_TEST__( mm_radio_destroy( g_my_radio ); ) - g_my_radio = 0; - } - break; - - case 3: - { - RADIO_TEST__( mm_radio_realize(g_my_radio ); ) - } - break; - - case 4: - { - RADIO_TEST__( mm_radio_unrealize(g_my_radio ); ) - } - break; - - case 7: - { - MMRadioStateType state = 0; - RADIO_TEST__( mm_radio_get_state(g_my_radio, &state); ) - - printf("state : %d\n", state); - } - break; - - case 8: - { - RADIO_TEST__( mm_radio_start(g_my_radio); ) - } - break; - - case 9: - { - RADIO_TEST__( mm_radio_stop(g_my_radio); ) - } - break; - - case 10: - { - MMRadioSeekDirectionType direction = 0; - printf("input seek direction(0:UP/1:DOWN) : "); - scanf("%d", &direction); - RADIO_TEST__( mm_radio_seek(g_my_radio, direction); ) - } - break; - - case 11: - { - int freq = 0; - printf("input freq : "); - scanf("%d", &freq); - RADIO_TEST__( mm_radio_set_frequency(g_my_radio, freq); ) - } - break; - - case 12: - { - int freq = 0; - RADIO_TEST__( mm_radio_get_frequency(g_my_radio, &freq ); ) - - printf("freq : %d\n", freq); - } - break; - - case 13: - { - RADIO_TEST__( mm_radio_scan_start(g_my_radio); ) - } - break; - - case 14: - { - RADIO_TEST__( mm_radio_scan_stop(g_my_radio); ) - } - break; - - default: - break; - } -} - -int main(int argc, char **argv) -{ - while(1) - { - char key = 0; - int choosen = 0; - - choosen = __menu(); - - if ( choosen == -1) - continue; - - if ( choosen == 0 ) - break; - - __call_api( choosen ); - } -} - * @endcode */ int mm_radio_destroy(MMHandleType hradio); @@ -531,217 +142,12 @@ int mm_radio_destroy(MMHandleType hradio); * @remark None * @see mm_radio_create mm_radio_destroy mm_radio_unrealize mm_radio_start mm_radio_stop * @par Example - * @code -#include -#include -#include - -#define RADIO_TEST__(x_test) \ - ret = x_test \ - if ( ! ret ) \ - { \ - printf("PASS : %s -- %s:%d\n", #x_test, __FILE__, __LINE__); \ - } \ - else \ - { \ - printf("FAIL : %s ERR-CODE : %d -- %s:%d\n", #x_test, ret, __FILE__, __LINE__); \ - } - -static MMHandleType g_my_radio = 0; - -int __menu(void) -{ - int menu_item = 0; - - printf("---------------------------------------------------------\n"); - printf("mm-radio rt api test. try now!\n"); - printf("---------------------------------------------------------\n"); - printf("[1] mm_radio_create\n"); - printf("[2] mm_radio_destroy\n"); - printf("[3] mm_radio_realize\n"); - printf("[4] mm_radio_unrealize\n"); - printf("[7] mm_radio_get_state\n"); - printf("[8] mm_radio_start\n"); - printf("[9] mm_radio_stop\n"); - printf("[10] mm_radio_seek\n"); - printf("[11] mm_radio_set_frequency\n"); - printf("[12] mm_radio_get_frequency\n"); - printf("[13] mm_radio_scan_start\n"); - printf("[14] mm_radio_scan_stop\n"); - printf("[0] quit\n"); - printf("---------------------------------------------------------\n"); - printf("choose one : "); - scanf("%d", &menu_item); - - if ( menu_item > 15 ) - menu_item = -1; - - return menu_item; -} - -int __msg_rt_callback(int message, void *pParam, void *user_param) -{ - MMMessageParamType* param = (MMMessageParamType*)pParam; - int ret = 0; - - printf("incomming message : %d\n", message); - - switch(message) - { - case MM_MESSAGE_STATE_CHANGED: - - printf("MM_MESSAGE_STATE_CHANGED: current : %d old : %d\n" - , param->state.current, param->state.previous); - break; - case MM_MESSAGE_RADIO_SCAN_START: - printf("MM_MESSAGE_RADIO_SCAN_START\n"); - break; - case MM_MESSAGE_RADIO_SCAN_INFO: - assert(param); - printf("MM_MESSAGE_RADIO_SCAN_INFO : freq : %d\n", param->radio_scan.frequency); - break; - case MM_MESSAGE_RADIO_SCAN_STOP: - printf("MM_MESSAGE_RADIO_SCAN_STOP\n"); - break; - case MM_MESSAGE_RADIO_SCAN_FINISH: - printf("MM_MESSAGE_RADIO_SCAN_FINISHED\n"); - break; - case MM_MESSAGE_RADIO_SEEK_START: - printf("MM_MESSAGE_RADIO_SEEK_START\n"); - break; - case MM_MESSAGE_RADIO_SEEK_FINISH: - printf("MM_MESSAGE_RADIO_SEEK_FINISHED : freq : %d\n", param->radio_scan.frequency); - break; - default: - printf("ERROR : unknown message received!\n"); - break; - } - - return true; -} - -void __call_api( int choosen ) -{ - int ret = MM_ERROR_NONE; - - switch( choosen ) - { - case 1: - { - RADIO_TEST__( mm_radio_create( &g_my_radio ); ) - RADIO_TEST__( mm_radio_set_message_callback( g_my_radio, __msg_rt_callback, &g_my_radio); ) - } - break; - - case 2: - { - RADIO_TEST__( mm_radio_destroy( g_my_radio ); ) - g_my_radio = 0; - } - break; - - case 3: - { - RADIO_TEST__( mm_radio_realize(g_my_radio ); ) - } - break; - - case 4: - { - RADIO_TEST__( mm_radio_unrealize(g_my_radio ); ) - } - break; - - case 7: - { - MMRadioStateType state = 0; - RADIO_TEST__( mm_radio_get_state(g_my_radio, &state); ) - - printf("state : %d\n", state); - } - break; - - case 8: - { - RADIO_TEST__( mm_radio_start(g_my_radio); ) - } - break; - - case 9: - { - RADIO_TEST__( mm_radio_stop(g_my_radio); ) - } - break; - - case 10: - { - MMRadioSeekDirectionType direction = 0; - printf("input seek direction(0:UP/1:DOWN) : "); - scanf("%d", &direction); - RADIO_TEST__( mm_radio_seek(g_my_radio, direction); ) - } - break; - - case 11: - { - int freq = 0; - printf("input freq : "); - scanf("%d", &freq); - RADIO_TEST__( mm_radio_set_frequency(g_my_radio, freq); ) - } - break; - - case 12: - { - int freq = 0; - RADIO_TEST__( mm_radio_get_frequency(g_my_radio, &freq ); ) - - printf("freq : %d\n", freq); - } - break; - - case 13: - { - RADIO_TEST__( mm_radio_scan_start(g_my_radio); ) - } - break; - - case 14: - { - RADIO_TEST__( mm_radio_scan_stop(g_my_radio); ) - } - break; - - default: - break; - } -} - -int main(int argc, char **argv) -{ - while(1) - { - char key = 0; - int choosen = 0; - - choosen = __menu(); - - if ( choosen == -1) - continue; - - if ( choosen == 0 ) - break; - - __call_api( choosen ); - } -} - * @endcode */ int mm_radio_realize(MMHandleType hradio); /** * This function mutes tuner and closes the radio device. - * And, application can destroy radio directly without this API. + * And, application can destroy radio directly without this API. * * @param hradio [in] Handle of radio. * @@ -751,211 +157,6 @@ int mm_radio_realize(MMHandleType hradio); * @remark None * @see mm_radio_create mm_radio_destroy mm_radio_realize mm_radio_start mm_radio_stop * @par Example - * @code -#include -#include -#include - -#define RADIO_TEST__(x_test) \ - ret = x_test \ - if ( ! ret ) \ - { \ - printf("PASS : %s -- %s:%d\n", #x_test, __FILE__, __LINE__); \ - } \ - else \ - { \ - printf("FAIL : %s ERR-CODE : %d -- %s:%d\n", #x_test, ret, __FILE__, __LINE__); \ - } - -static MMHandleType g_my_radio = 0; - -int __menu(void) -{ - int menu_item = 0; - - printf("---------------------------------------------------------\n"); - printf("mm-radio rt api test. try now!\n"); - printf("---------------------------------------------------------\n"); - printf("[1] mm_radio_create\n"); - printf("[2] mm_radio_destroy\n"); - printf("[3] mm_radio_realize\n"); - printf("[4] mm_radio_unrealize\n"); - printf("[7] mm_radio_get_state\n"); - printf("[8] mm_radio_start\n"); - printf("[9] mm_radio_stop\n"); - printf("[10] mm_radio_seek\n"); - printf("[11] mm_radio_set_frequency\n"); - printf("[12] mm_radio_get_frequency\n"); - printf("[13] mm_radio_scan_start\n"); - printf("[14] mm_radio_scan_stop\n"); - printf("[0] quit\n"); - printf("---------------------------------------------------------\n"); - printf("choose one : "); - scanf("%d", &menu_item); - - if ( menu_item > 15 ) - menu_item = -1; - - return menu_item; -} - -int __msg_rt_callback(int message, void *pParam, void *user_param) -{ - MMMessageParamType* param = (MMMessageParamType*)pParam; - int ret = 0; - - printf("incomming message : %d\n", message); - - switch(message) - { - case MM_MESSAGE_STATE_CHANGED: - - printf("MM_MESSAGE_STATE_CHANGED: current : %d old : %d\n" - , param->state.current, param->state.previous); - break; - case MM_MESSAGE_RADIO_SCAN_START: - printf("MM_MESSAGE_RADIO_SCAN_START\n"); - break; - case MM_MESSAGE_RADIO_SCAN_INFO: - assert(param); - printf("MM_MESSAGE_RADIO_SCAN_INFO : freq : %d\n", param->radio_scan.frequency); - break; - case MM_MESSAGE_RADIO_SCAN_STOP: - printf("MM_MESSAGE_RADIO_SCAN_STOP\n"); - break; - case MM_MESSAGE_RADIO_SCAN_FINISH: - printf("MM_MESSAGE_RADIO_SCAN_FINISHED\n"); - break; - case MM_MESSAGE_RADIO_SEEK_START: - printf("MM_MESSAGE_RADIO_SEEK_START\n"); - break; - case MM_MESSAGE_RADIO_SEEK_FINISH: - printf("MM_MESSAGE_RADIO_SEEK_FINISHED : freq : %d\n", param->radio_scan.frequency); - break; - default: - printf("ERROR : unknown message received!\n"); - break; - } - - return true; -} - -void __call_api( int choosen ) -{ - int ret = MM_ERROR_NONE; - - switch( choosen ) - { - case 1: - { - RADIO_TEST__( mm_radio_create( &g_my_radio ); ) - RADIO_TEST__( mm_radio_set_message_callback( g_my_radio, __msg_rt_callback, &g_my_radio); ) - } - break; - - case 2: - { - RADIO_TEST__( mm_radio_destroy( g_my_radio ); ) - g_my_radio = 0; - } - break; - - case 3: - { - RADIO_TEST__( mm_radio_realize(g_my_radio ); ) - } - break; - - case 4: - { - RADIO_TEST__( mm_radio_unrealize(g_my_radio ); ) - } - break; - - case 7: - { - MMRadioStateType state = 0; - RADIO_TEST__( mm_radio_get_state(g_my_radio, &state); ) - - printf("state : %d\n", state); - } - break; - - case 8: - { - RADIO_TEST__( mm_radio_start(g_my_radio); ) - } - break; - - case 9: - { - RADIO_TEST__( mm_radio_stop(g_my_radio); ) - } - break; - - case 10: - { - MMRadioSeekDirectionType direction = 0; - printf("input seek direction(0:UP/1:DOWN) : "); - scanf("%d", &direction); - RADIO_TEST__( mm_radio_seek(g_my_radio, direction); ) - } - break; - - case 11: - { - int freq = 0; - printf("input freq : "); - scanf("%d", &freq); - RADIO_TEST__( mm_radio_set_frequency(g_my_radio, freq); ) - } - break; - - case 12: - { - int freq = 0; - RADIO_TEST__( mm_radio_get_frequency(g_my_radio, &freq ); ) - - printf("freq : %d\n", freq); - } - break; - - case 13: - { - RADIO_TEST__( mm_radio_scan_start(g_my_radio); ) - } - break; - - case 14: - { - RADIO_TEST__( mm_radio_scan_stop(g_my_radio); ) - } - break; - - default: - break; - } -} - -int main(int argc, char **argv) -{ - while(1) - { - char key = 0; - int choosen = 0; - - choosen = __menu(); - - if ( choosen == -1) - continue; - - if ( choosen == 0 ) - break; - - __call_api( choosen ); - } -} - * @endcode */ int mm_radio_unrealize(MMHandleType hradio); @@ -972,211 +173,6 @@ int mm_radio_unrealize(MMHandleType hradio); * @remark None * @see * @par Example - * @code -#include -#include -#include - -#define RADIO_TEST__(x_test) \ - ret = x_test \ - if ( ! ret ) \ - { \ - printf("PASS : %s -- %s:%d\n", #x_test, __FILE__, __LINE__); \ - } \ - else \ - { \ - printf("FAIL : %s ERR-CODE : %d -- %s:%d\n", #x_test, ret, __FILE__, __LINE__); \ - } - -static MMHandleType g_my_radio = 0; - -int __menu(void) -{ - int menu_item = 0; - - printf("---------------------------------------------------------\n"); - printf("mm-radio rt api test. try now!\n"); - printf("---------------------------------------------------------\n"); - printf("[1] mm_radio_create\n"); - printf("[2] mm_radio_destroy\n"); - printf("[3] mm_radio_realize\n"); - printf("[4] mm_radio_unrealize\n"); - printf("[7] mm_radio_get_state\n"); - printf("[8] mm_radio_start\n"); - printf("[9] mm_radio_stop\n"); - printf("[10] mm_radio_seek\n"); - printf("[11] mm_radio_set_frequency\n"); - printf("[12] mm_radio_get_frequency\n"); - printf("[13] mm_radio_scan_start\n"); - printf("[14] mm_radio_scan_stop\n"); - printf("[0] quit\n"); - printf("---------------------------------------------------------\n"); - printf("choose one : "); - scanf("%d", &menu_item); - - if ( menu_item > 15 ) - menu_item = -1; - - return menu_item; -} - -int __msg_rt_callback(int message, void *pParam, void *user_param) -{ - MMMessageParamType* param = (MMMessageParamType*)pParam; - int ret = 0; - - printf("incomming message : %d\n", message); - - switch(message) - { - case MM_MESSAGE_STATE_CHANGED: - - printf("MM_MESSAGE_STATE_CHANGED: current : %d old : %d\n" - , param->state.current, param->state.previous); - break; - case MM_MESSAGE_RADIO_SCAN_START: - printf("MM_MESSAGE_RADIO_SCAN_START\n"); - break; - case MM_MESSAGE_RADIO_SCAN_INFO: - assert(param); - printf("MM_MESSAGE_RADIO_SCAN_INFO : freq : %d\n", param->radio_scan.frequency); - break; - case MM_MESSAGE_RADIO_SCAN_STOP: - printf("MM_MESSAGE_RADIO_SCAN_STOP\n"); - break; - case MM_MESSAGE_RADIO_SCAN_FINISH: - printf("MM_MESSAGE_RADIO_SCAN_FINISHED\n"); - break; - case MM_MESSAGE_RADIO_SEEK_START: - printf("MM_MESSAGE_RADIO_SEEK_START\n"); - break; - case MM_MESSAGE_RADIO_SEEK_FINISH: - printf("MM_MESSAGE_RADIO_SEEK_FINISHED : freq : %d\n", param->radio_scan.frequency); - break; - default: - printf("ERROR : unknown message received!\n"); - break; - } - - return true; -} - -void __call_api( int choosen ) -{ - int ret = MM_ERROR_NONE; - - switch( choosen ) - { - case 1: - { - RADIO_TEST__( mm_radio_create( &g_my_radio ); ) - RADIO_TEST__( mm_radio_set_message_callback( g_my_radio, __msg_rt_callback, &g_my_radio); ) - } - break; - - case 2: - { - RADIO_TEST__( mm_radio_destroy( g_my_radio ); ) - g_my_radio = 0; - } - break; - - case 3: - { - RADIO_TEST__( mm_radio_realize(g_my_radio ); ) - } - break; - - case 4: - { - RADIO_TEST__( mm_radio_unrealize(g_my_radio ); ) - } - break; - - case 7: - { - MMRadioStateType state = 0; - RADIO_TEST__( mm_radio_get_state(g_my_radio, &state); ) - - printf("state : %d\n", state); - } - break; - - case 8: - { - RADIO_TEST__( mm_radio_start(g_my_radio); ) - } - break; - - case 9: - { - RADIO_TEST__( mm_radio_stop(g_my_radio); ) - } - break; - - case 10: - { - MMRadioSeekDirectionType direction = 0; - printf("input seek direction(0:UP/1:DOWN) : "); - scanf("%d", &direction); - RADIO_TEST__( mm_radio_seek(g_my_radio, direction); ) - } - break; - - case 11: - { - int freq = 0; - printf("input freq : "); - scanf("%d", &freq); - RADIO_TEST__( mm_radio_set_frequency(g_my_radio, freq); ) - } - break; - - case 12: - { - int freq = 0; - RADIO_TEST__( mm_radio_get_frequency(g_my_radio, &freq ); ) - - printf("freq : %d\n", freq); - } - break; - - case 13: - { - RADIO_TEST__( mm_radio_scan_start(g_my_radio); ) - } - break; - - case 14: - { - RADIO_TEST__( mm_radio_scan_stop(g_my_radio); ) - } - break; - - default: - break; - } -} - -int main(int argc, char **argv) -{ - while(1) - { - char key = 0; - int choosen = 0; - - choosen = __menu(); - - if ( choosen == -1) - continue; - - if ( choosen == 0 ) - break; - - __call_api( choosen ); - } -} - * @endcode */ int mm_radio_set_message_callback(MMHandleType hradio, MMMessageCallback callback, void *user_param); @@ -1192,211 +188,6 @@ int mm_radio_set_message_callback(MMHandleType hradio, MMMessageCallback callbac * @remark None * @see * @par Example - * @code -#include -#include -#include - -#define RADIO_TEST__(x_test) \ - ret = x_test \ - if ( ! ret ) \ - { \ - printf("PASS : %s -- %s:%d\n", #x_test, __FILE__, __LINE__); \ - } \ - else \ - { \ - printf("FAIL : %s ERR-CODE : %d -- %s:%d\n", #x_test, ret, __FILE__, __LINE__); \ - } - -static MMHandleType g_my_radio = 0; - -int __menu(void) -{ - int menu_item = 0; - - printf("---------------------------------------------------------\n"); - printf("mm-radio rt api test. try now!\n"); - printf("---------------------------------------------------------\n"); - printf("[1] mm_radio_create\n"); - printf("[2] mm_radio_destroy\n"); - printf("[3] mm_radio_realize\n"); - printf("[4] mm_radio_unrealize\n"); - printf("[7] mm_radio_get_state\n"); - printf("[8] mm_radio_start\n"); - printf("[9] mm_radio_stop\n"); - printf("[10] mm_radio_seek\n"); - printf("[11] mm_radio_set_frequency\n"); - printf("[12] mm_radio_get_frequency\n"); - printf("[13] mm_radio_scan_start\n"); - printf("[14] mm_radio_scan_stop\n"); - printf("[0] quit\n"); - printf("---------------------------------------------------------\n"); - printf("choose one : "); - scanf("%d", &menu_item); - - if ( menu_item > 15 ) - menu_item = -1; - - return menu_item; -} - -int __msg_rt_callback(int message, void *pParam, void *user_param) -{ - MMMessageParamType* param = (MMMessageParamType*)pParam; - int ret = 0; - - printf("incomming message : %d\n", message); - - switch(message) - { - case MM_MESSAGE_STATE_CHANGED: - - printf("MM_MESSAGE_STATE_CHANGED: current : %d old : %d\n" - , param->state.current, param->state.previous); - break; - case MM_MESSAGE_RADIO_SCAN_START: - printf("MM_MESSAGE_RADIO_SCAN_START\n"); - break; - case MM_MESSAGE_RADIO_SCAN_INFO: - assert(param); - printf("MM_MESSAGE_RADIO_SCAN_INFO : freq : %d\n", param->radio_scan.frequency); - break; - case MM_MESSAGE_RADIO_SCAN_STOP: - printf("MM_MESSAGE_RADIO_SCAN_STOP\n"); - break; - case MM_MESSAGE_RADIO_SCAN_FINISH: - printf("MM_MESSAGE_RADIO_SCAN_FINISHED\n"); - break; - case MM_MESSAGE_RADIO_SEEK_START: - printf("MM_MESSAGE_RADIO_SEEK_START\n"); - break; - case MM_MESSAGE_RADIO_SEEK_FINISH: - printf("MM_MESSAGE_RADIO_SEEK_FINISHED : freq : %d\n", param->radio_scan.frequency); - break; - default: - printf("ERROR : unknown message received!\n"); - break; - } - - return true; -} - -void __call_api( int choosen ) -{ - int ret = MM_ERROR_NONE; - - switch( choosen ) - { - case 1: - { - RADIO_TEST__( mm_radio_create( &g_my_radio ); ) - RADIO_TEST__( mm_radio_set_message_callback( g_my_radio, __msg_rt_callback, &g_my_radio); ) - } - break; - - case 2: - { - RADIO_TEST__( mm_radio_destroy( g_my_radio ); ) - g_my_radio = 0; - } - break; - - case 3: - { - RADIO_TEST__( mm_radio_realize(g_my_radio ); ) - } - break; - - case 4: - { - RADIO_TEST__( mm_radio_unrealize(g_my_radio ); ) - } - break; - - case 7: - { - MMRadioStateType state = 0; - RADIO_TEST__( mm_radio_get_state(g_my_radio, &state); ) - - printf("state : %d\n", state); - } - break; - - case 8: - { - RADIO_TEST__( mm_radio_start(g_my_radio); ) - } - break; - - case 9: - { - RADIO_TEST__( mm_radio_stop(g_my_radio); ) - } - break; - - case 10: - { - MMRadioSeekDirectionType direction = 0; - printf("input seek direction(0:UP/1:DOWN) : "); - scanf("%d", &direction); - RADIO_TEST__( mm_radio_seek(g_my_radio, direction); ) - } - break; - - case 11: - { - int freq = 0; - printf("input freq : "); - scanf("%d", &freq); - RADIO_TEST__( mm_radio_set_frequency(g_my_radio, freq); ) - } - break; - - case 12: - { - int freq = 0; - RADIO_TEST__( mm_radio_get_frequency(g_my_radio, &freq ); ) - - printf("freq : %d\n", freq); - } - break; - - case 13: - { - RADIO_TEST__( mm_radio_scan_start(g_my_radio); ) - } - break; - - case 14: - { - RADIO_TEST__( mm_radio_scan_stop(g_my_radio); ) - } - break; - - default: - break; - } -} - -int main(int argc, char **argv) -{ - while(1) - { - char key = 0; - int choosen = 0; - - choosen = __menu(); - - if ( choosen == -1) - continue; - - if ( choosen == 0 ) - break; - - __call_api( choosen ); - } -} - * @endcode */ int mm_radio_get_state(MMHandleType hradio, MMRadioStateType *state); @@ -1411,434 +202,22 @@ int mm_radio_get_state(MMHandleType hradio, MMRadioStateType *state); * @remark None * @see mm_radio_create mm_radio_destroy mm_radio_realize mm_radio_unrealize mm_radio_stop * @par Example - * @code -#include -#include -#include - -#define RADIO_TEST__(x_test) \ - ret = x_test \ - if ( ! ret ) \ - { \ - printf("PASS : %s -- %s:%d\n", #x_test, __FILE__, __LINE__); \ - } \ - else \ - { \ - printf("FAIL : %s ERR-CODE : %d -- %s:%d\n", #x_test, ret, __FILE__, __LINE__); \ - } - -static MMHandleType g_my_radio = 0; - -int __menu(void) -{ - int menu_item = 0; - - printf("---------------------------------------------------------\n"); - printf("mm-radio rt api test. try now!\n"); - printf("---------------------------------------------------------\n"); - printf("[1] mm_radio_create\n"); - printf("[2] mm_radio_destroy\n"); - printf("[3] mm_radio_realize\n"); - printf("[4] mm_radio_unrealize\n"); - printf("[7] mm_radio_get_state\n"); - printf("[8] mm_radio_start\n"); - printf("[9] mm_radio_stop\n"); - printf("[10] mm_radio_seek\n"); - printf("[11] mm_radio_set_frequency\n"); - printf("[12] mm_radio_get_frequency\n"); - printf("[13] mm_radio_scan_start\n"); - printf("[14] mm_radio_scan_stop\n"); - printf("[0] quit\n"); - printf("---------------------------------------------------------\n"); - printf("choose one : "); - scanf("%d", &menu_item); - - if ( menu_item > 15 ) - menu_item = -1; - - return menu_item; -} - -int __msg_rt_callback(int message, void *pParam, void *user_param) -{ - MMMessageParamType* param = (MMMessageParamType*)pParam; - int ret = 0; - - printf("incomming message : %d\n", message); - - switch(message) - { - case MM_MESSAGE_STATE_CHANGED: - - printf("MM_MESSAGE_STATE_CHANGED: current : %d old : %d\n" - , param->state.current, param->state.previous); - break; - case MM_MESSAGE_RADIO_SCAN_START: - printf("MM_MESSAGE_RADIO_SCAN_START\n"); - break; - case MM_MESSAGE_RADIO_SCAN_INFO: - assert(param); - printf("MM_MESSAGE_RADIO_SCAN_INFO : freq : %d\n", param->radio_scan.frequency); - break; - case MM_MESSAGE_RADIO_SCAN_STOP: - printf("MM_MESSAGE_RADIO_SCAN_STOP\n"); - break; - case MM_MESSAGE_RADIO_SCAN_FINISH: - printf("MM_MESSAGE_RADIO_SCAN_FINISHED\n"); - break; - case MM_MESSAGE_RADIO_SEEK_START: - printf("MM_MESSAGE_RADIO_SEEK_START\n"); - break; - case MM_MESSAGE_RADIO_SEEK_FINISH: - printf("MM_MESSAGE_RADIO_SEEK_FINISHED : freq : %d\n", param->radio_scan.frequency); - break; - default: - printf("ERROR : unknown message received!\n"); - break; - } - - return true; -} - -void __call_api( int choosen ) -{ - int ret = MM_ERROR_NONE; - - switch( choosen ) - { - case 1: - { - RADIO_TEST__( mm_radio_create( &g_my_radio ); ) - RADIO_TEST__( mm_radio_set_message_callback( g_my_radio, __msg_rt_callback, &g_my_radio); ) - } - break; - - case 2: - { - RADIO_TEST__( mm_radio_destroy( g_my_radio ); ) - g_my_radio = 0; - } - break; + */ +int mm_radio_start(MMHandleType hradio); - case 3: - { - RADIO_TEST__( mm_radio_realize(g_my_radio ); ) - } - break; - - case 4: - { - RADIO_TEST__( mm_radio_unrealize(g_my_radio ); ) - } - break; - - case 7: - { - MMRadioStateType state = 0; - RADIO_TEST__( mm_radio_get_state(g_my_radio, &state); ) - - printf("state : %d\n", state); - } - break; - - case 8: - { - RADIO_TEST__( mm_radio_start(g_my_radio); ) - } - break; - - case 9: - { - RADIO_TEST__( mm_radio_stop(g_my_radio); ) - } - break; - - case 10: - { - MMRadioSeekDirectionType direction = 0; - printf("input seek direction(0:UP/1:DOWN) : "); - scanf("%d", &direction); - RADIO_TEST__( mm_radio_seek(g_my_radio, direction); ) - } - break; - - case 11: - { - int freq = 0; - printf("input freq : "); - scanf("%d", &freq); - RADIO_TEST__( mm_radio_set_frequency(g_my_radio, freq); ) - } - break; - - case 12: - { - int freq = 0; - RADIO_TEST__( mm_radio_get_frequency(g_my_radio, &freq ); ) - - printf("freq : %d\n", freq); - } - break; - - case 13: - { - RADIO_TEST__( mm_radio_scan_start(g_my_radio); ) - } - break; - - case 14: - { - RADIO_TEST__( mm_radio_scan_stop(g_my_radio); ) - } - break; - - default: - break; - } -} - -int main(int argc, char **argv) -{ - while(1) - { - char key = 0; - int choosen = 0; - - choosen = __menu(); - - if ( choosen == -1) - continue; - - if ( choosen == 0 ) - break; - - __call_api( choosen ); - } -} - - * @endcode - */ -int mm_radio_start(MMHandleType hradio); - -/** - * This function is to stop playing radio. - * - * @param hradio [in] Handle of radio. - * - * @return This function returns zero on success, or negative value with errors - * @pre MM_RADIO_STATE_PLAYING - * @post MM_RADIO_STATE_READY - * @remark None - * @see mm_radio_create mm_radio_destroy mm_radio_realize mm_radio_unrealize mm_radio_start - * @par Example - * @code -#include -#include -#include - -#define RADIO_TEST__(x_test) \ - ret = x_test \ - if ( ! ret ) \ - { \ - printf("PASS : %s -- %s:%d\n", #x_test, __FILE__, __LINE__); \ - } \ - else \ - { \ - printf("FAIL : %s ERR-CODE : %d -- %s:%d\n", #x_test, ret, __FILE__, __LINE__); \ - } - -static MMHandleType g_my_radio = 0; - -int __menu(void) -{ - int menu_item = 0; - - printf("---------------------------------------------------------\n"); - printf("mm-radio rt api test. try now!\n"); - printf("---------------------------------------------------------\n"); - printf("[1] mm_radio_create\n"); - printf("[2] mm_radio_destroy\n"); - printf("[3] mm_radio_realize\n"); - printf("[4] mm_radio_unrealize\n"); - printf("[7] mm_radio_get_state\n"); - printf("[8] mm_radio_start\n"); - printf("[9] mm_radio_stop\n"); - printf("[10] mm_radio_seek\n"); - printf("[11] mm_radio_set_frequency\n"); - printf("[12] mm_radio_get_frequency\n"); - printf("[13] mm_radio_scan_start\n"); - printf("[14] mm_radio_scan_stop\n"); - printf("[0] quit\n"); - printf("---------------------------------------------------------\n"); - printf("choose one : "); - scanf("%d", &menu_item); - - if ( menu_item > 15 ) - menu_item = -1; - - return menu_item; -} - -int __msg_rt_callback(int message, void *pParam, void *user_param) -{ - MMMessageParamType* param = (MMMessageParamType*)pParam; - int ret = 0; - - printf("incomming message : %d\n", message); - - switch(message) - { - case MM_MESSAGE_STATE_CHANGED: - - printf("MM_MESSAGE_STATE_CHANGED: current : %d old : %d\n" - , param->state.current, param->state.previous); - break; - case MM_MESSAGE_RADIO_SCAN_START: - printf("MM_MESSAGE_RADIO_SCAN_START\n"); - break; - case MM_MESSAGE_RADIO_SCAN_INFO: - assert(param); - printf("MM_MESSAGE_RADIO_SCAN_INFO : freq : %d\n", param->radio_scan.frequency); - break; - case MM_MESSAGE_RADIO_SCAN_STOP: - printf("MM_MESSAGE_RADIO_SCAN_STOP\n"); - break; - case MM_MESSAGE_RADIO_SCAN_FINISH: - printf("MM_MESSAGE_RADIO_SCAN_FINISHED\n"); - break; - case MM_MESSAGE_RADIO_SEEK_START: - printf("MM_MESSAGE_RADIO_SEEK_START\n"); - break; - case MM_MESSAGE_RADIO_SEEK_FINISH: - printf("MM_MESSAGE_RADIO_SEEK_FINISHED : freq : %d\n", param->radio_scan.frequency); - break; - default: - printf("ERROR : unknown message received!\n"); - break; - } - - return true; -} - -void __call_api( int choosen ) -{ - int ret = MM_ERROR_NONE; - - switch( choosen ) - { - case 1: - { - RADIO_TEST__( mm_radio_create( &g_my_radio ); ) - RADIO_TEST__( mm_radio_set_message_callback( g_my_radio, __msg_rt_callback, &g_my_radio); ) - } - break; - - case 2: - { - RADIO_TEST__( mm_radio_destroy( g_my_radio ); ) - g_my_radio = 0; - } - break; - - case 3: - { - RADIO_TEST__( mm_radio_realize(g_my_radio ); ) - } - break; - - case 4: - { - RADIO_TEST__( mm_radio_unrealize(g_my_radio ); ) - } - break; - - case 7: - { - MMRadioStateType state = 0; - RADIO_TEST__( mm_radio_get_state(g_my_radio, &state); ) - - printf("state : %d\n", state); - } - break; - - case 8: - { - RADIO_TEST__( mm_radio_start(g_my_radio); ) - } - break; - - case 9: - { - RADIO_TEST__( mm_radio_stop(g_my_radio); ) - } - break; - - case 10: - { - MMRadioSeekDirectionType direction = 0; - printf("input seek direction(0:UP/1:DOWN) : "); - scanf("%d", &direction); - RADIO_TEST__( mm_radio_seek(g_my_radio, direction); ) - } - break; - - case 11: - { - int freq = 0; - printf("input freq : "); - scanf("%d", &freq); - RADIO_TEST__( mm_radio_set_frequency(g_my_radio, freq); ) - } - break; - - case 12: - { - int freq = 0; - RADIO_TEST__( mm_radio_get_frequency(g_my_radio, &freq ); ) - - printf("freq : %d\n", freq); - } - break; - - case 13: - { - RADIO_TEST__( mm_radio_scan_start(g_my_radio); ) - } - break; - - case 14: - { - RADIO_TEST__( mm_radio_scan_stop(g_my_radio); ) - } - break; - - default: - break; - } -} - -int main(int argc, char **argv) -{ - while(1) - { - char key = 0; - int choosen = 0; - - choosen = __menu(); - - if ( choosen == -1) - continue; - - if ( choosen == 0 ) - break; - - __call_api( choosen ); - } -} - - * @endcode - */ -int mm_radio_stop(MMHandleType hradio); +/** + * This function is to stop playing radio. + * + * @param hradio [in] Handle of radio. + * + * @return This function returns zero on success, or negative value with errors + * @pre MM_RADIO_STATE_PLAYING + * @post MM_RADIO_STATE_READY + * @remark None + * @see mm_radio_create mm_radio_destroy mm_radio_realize mm_radio_unrealize mm_radio_start + * @par Example + */ +int mm_radio_stop(MMHandleType hradio); /** * This function seeks the effective frequency of radio. The application get a valid frequency from current value. \n @@ -1846,8 +225,8 @@ int mm_radio_stop(MMHandleType hradio); * MM_MESSAGE_RADIO_SEEK_START will be sent when this function is called. \n * And if one valid frequency is found, MM_MESSAGE_RADIO_SEEK_FINISH will be sent. \n * It doesn't support wrap_around to prevent looping when there is no any valid frequency. \n - * So, we will notice the limit of band as 87.5Mhz or 108Mhz. - * In this case, applicaion can take two scenario. + * So, we will notice the limit of band as 87.5Mhz or 108Mhz. + * In this case, applicaion can take two scenario. * One is to seek continually in the same direction. The other is to set previous frequency. * * @param hradio [in] Handle of radio. @@ -1859,212 +238,6 @@ int mm_radio_stop(MMHandleType hradio); * @remark None * @see MM_MESSAGE_RADIO_SEEK_START MM_MESSAGE_RADIO_SEEK_FINISH * @par Example - * @code -#include -#include -#include - -#define RADIO_TEST__(x_test) \ - ret = x_test \ - if ( ! ret ) \ - { \ - printf("PASS : %s -- %s:%d\n", #x_test, __FILE__, __LINE__); \ - } \ - else \ - { \ - printf("FAIL : %s ERR-CODE : %d -- %s:%d\n", #x_test, ret, __FILE__, __LINE__); \ - } - -static MMHandleType g_my_radio = 0; - -int __menu(void) -{ - int menu_item = 0; - - printf("---------------------------------------------------------\n"); - printf("mm-radio rt api test. try now!\n"); - printf("---------------------------------------------------------\n"); - printf("[1] mm_radio_create\n"); - printf("[2] mm_radio_destroy\n"); - printf("[3] mm_radio_realize\n"); - printf("[4] mm_radio_unrealize\n"); - printf("[7] mm_radio_get_state\n"); - printf("[8] mm_radio_start\n"); - printf("[9] mm_radio_stop\n"); - printf("[10] mm_radio_seek\n"); - printf("[11] mm_radio_set_frequency\n"); - printf("[12] mm_radio_get_frequency\n"); - printf("[13] mm_radio_scan_start\n"); - printf("[14] mm_radio_scan_stop\n"); - printf("[0] quit\n"); - printf("---------------------------------------------------------\n"); - printf("choose one : "); - scanf("%d", &menu_item); - - if ( menu_item > 15 ) - menu_item = -1; - - return menu_item; -} - -int __msg_rt_callback(int message, void *pParam, void *user_param) -{ - MMMessageParamType* param = (MMMessageParamType*)pParam; - int ret = 0; - - printf("incomming message : %d\n", message); - - switch(message) - { - case MM_MESSAGE_STATE_CHANGED: - - printf("MM_MESSAGE_STATE_CHANGED: current : %d old : %d\n" - , param->state.current, param->state.previous); - break; - case MM_MESSAGE_RADIO_SCAN_START: - printf("MM_MESSAGE_RADIO_SCAN_START\n"); - break; - case MM_MESSAGE_RADIO_SCAN_INFO: - assert(param); - printf("MM_MESSAGE_RADIO_SCAN_INFO : freq : %d\n", param->radio_scan.frequency); - break; - case MM_MESSAGE_RADIO_SCAN_STOP: - printf("MM_MESSAGE_RADIO_SCAN_STOP\n"); - break; - case MM_MESSAGE_RADIO_SCAN_FINISH: - printf("MM_MESSAGE_RADIO_SCAN_FINISHED\n"); - break; - case MM_MESSAGE_RADIO_SEEK_START: - printf("MM_MESSAGE_RADIO_SEEK_START\n"); - break; - case MM_MESSAGE_RADIO_SEEK_FINISH: - printf("MM_MESSAGE_RADIO_SEEK_FINISHED : freq : %d\n", param->radio_scan.frequency); - break; - default: - printf("ERROR : unknown message received!\n"); - break; - } - - return true; -} - -void __call_api( int choosen ) -{ - int ret = MM_ERROR_NONE; - - switch( choosen ) - { - case 1: - { - RADIO_TEST__( mm_radio_create( &g_my_radio ); ) - RADIO_TEST__( mm_radio_set_message_callback( g_my_radio, __msg_rt_callback, &g_my_radio); ) - } - break; - - case 2: - { - RADIO_TEST__( mm_radio_destroy( g_my_radio ); ) - g_my_radio = 0; - } - break; - - case 3: - { - RADIO_TEST__( mm_radio_realize(g_my_radio ); ) - } - break; - - case 4: - { - RADIO_TEST__( mm_radio_unrealize(g_my_radio ); ) - } - break; - - case 7: - { - MMRadioStateType state = 0; - RADIO_TEST__( mm_radio_get_state(g_my_radio, &state); ) - - printf("state : %d\n", state); - } - break; - - case 8: - { - RADIO_TEST__( mm_radio_start(g_my_radio); ) - } - break; - - case 9: - { - RADIO_TEST__( mm_radio_stop(g_my_radio); ) - } - break; - - case 10: - { - MMRadioSeekDirectionType direction = 0; - printf("input seek direction(0:UP/1:DOWN) : "); - scanf("%d", &direction); - RADIO_TEST__( mm_radio_seek(g_my_radio, direction); ) - } - break; - - case 11: - { - int freq = 0; - printf("input freq : "); - scanf("%d", &freq); - RADIO_TEST__( mm_radio_set_frequency(g_my_radio, freq); ) - } - break; - - case 12: - { - int freq = 0; - RADIO_TEST__( mm_radio_get_frequency(g_my_radio, &freq ); ) - - printf("freq : %d\n", freq); - } - break; - - case 13: - { - RADIO_TEST__( mm_radio_scan_start(g_my_radio); ) - } - break; - - case 14: - { - RADIO_TEST__( mm_radio_scan_stop(g_my_radio); ) - } - break; - - default: - break; - } -} - -int main(int argc, char **argv) -{ - while(1) - { - char key = 0; - int choosen = 0; - - choosen = __menu(); - - if ( choosen == -1) - continue; - - if ( choosen == 0 ) - break; - - __call_api( choosen ); - } -} - - * @endcode */ int mm_radio_seek(MMHandleType hradio, MMRadioSeekDirectionType direction); @@ -2080,212 +253,6 @@ int mm_radio_seek(MMHandleType hradio, MMRadioSeekDirectionType direction); * @remark None * @see mm_radio_get_frequency * @par Example - * @code -#include -#include -#include - -#define RADIO_TEST__(x_test) \ - ret = x_test \ - if ( ! ret ) \ - { \ - printf("PASS : %s -- %s:%d\n", #x_test, __FILE__, __LINE__); \ - } \ - else \ - { \ - printf("FAIL : %s ERR-CODE : %d -- %s:%d\n", #x_test, ret, __FILE__, __LINE__); \ - } - -static MMHandleType g_my_radio = 0; - -int __menu(void) -{ - int menu_item = 0; - - printf("---------------------------------------------------------\n"); - printf("mm-radio rt api test. try now!\n"); - printf("---------------------------------------------------------\n"); - printf("[1] mm_radio_create\n"); - printf("[2] mm_radio_destroy\n"); - printf("[3] mm_radio_realize\n"); - printf("[4] mm_radio_unrealize\n"); - printf("[7] mm_radio_get_state\n"); - printf("[8] mm_radio_start\n"); - printf("[9] mm_radio_stop\n"); - printf("[10] mm_radio_seek\n"); - printf("[11] mm_radio_set_frequency\n"); - printf("[12] mm_radio_get_frequency\n"); - printf("[13] mm_radio_scan_start\n"); - printf("[14] mm_radio_scan_stop\n"); - printf("[0] quit\n"); - printf("---------------------------------------------------------\n"); - printf("choose one : "); - scanf("%d", &menu_item); - - if ( menu_item > 15 ) - menu_item = -1; - - return menu_item; -} - -int __msg_rt_callback(int message, void *pParam, void *user_param) -{ - MMMessageParamType* param = (MMMessageParamType*)pParam; - int ret = 0; - - printf("incomming message : %d\n", message); - - switch(message) - { - case MM_MESSAGE_STATE_CHANGED: - - printf("MM_MESSAGE_STATE_CHANGED: current : %d old : %d\n" - , param->state.current, param->state.previous); - break; - case MM_MESSAGE_RADIO_SCAN_START: - printf("MM_MESSAGE_RADIO_SCAN_START\n"); - break; - case MM_MESSAGE_RADIO_SCAN_INFO: - assert(param); - printf("MM_MESSAGE_RADIO_SCAN_INFO : freq : %d\n", param->radio_scan.frequency); - break; - case MM_MESSAGE_RADIO_SCAN_STOP: - printf("MM_MESSAGE_RADIO_SCAN_STOP\n"); - break; - case MM_MESSAGE_RADIO_SCAN_FINISH: - printf("MM_MESSAGE_RADIO_SCAN_FINISHED\n"); - break; - case MM_MESSAGE_RADIO_SEEK_START: - printf("MM_MESSAGE_RADIO_SEEK_START\n"); - break; - case MM_MESSAGE_RADIO_SEEK_FINISH: - printf("MM_MESSAGE_RADIO_SEEK_FINISHED : freq : %d\n", param->radio_scan.frequency); - break; - default: - printf("ERROR : unknown message received!\n"); - break; - } - - return true; -} - -void __call_api( int choosen ) -{ - int ret = MM_ERROR_NONE; - - switch( choosen ) - { - case 1: - { - RADIO_TEST__( mm_radio_create( &g_my_radio ); ) - RADIO_TEST__( mm_radio_set_message_callback( g_my_radio, __msg_rt_callback, &g_my_radio); ) - } - break; - - case 2: - { - RADIO_TEST__( mm_radio_destroy( g_my_radio ); ) - g_my_radio = 0; - } - break; - - case 3: - { - RADIO_TEST__( mm_radio_realize(g_my_radio ); ) - } - break; - - case 4: - { - RADIO_TEST__( mm_radio_unrealize(g_my_radio ); ) - } - break; - - case 7: - { - MMRadioStateType state = 0; - RADIO_TEST__( mm_radio_get_state(g_my_radio, &state); ) - - printf("state : %d\n", state); - } - break; - - case 8: - { - RADIO_TEST__( mm_radio_start(g_my_radio); ) - } - break; - - case 9: - { - RADIO_TEST__( mm_radio_stop(g_my_radio); ) - } - break; - - case 10: - { - MMRadioSeekDirectionType direction = 0; - printf("input seek direction(0:UP/1:DOWN) : "); - scanf("%d", &direction); - RADIO_TEST__( mm_radio_seek(g_my_radio, direction); ) - } - break; - - case 11: - { - int freq = 0; - printf("input freq : "); - scanf("%d", &freq); - RADIO_TEST__( mm_radio_set_frequency(g_my_radio, freq); ) - } - break; - - case 12: - { - int freq = 0; - RADIO_TEST__( mm_radio_get_frequency(g_my_radio, &freq ); ) - - printf("freq : %d\n", freq); - } - break; - - case 13: - { - RADIO_TEST__( mm_radio_scan_start(g_my_radio); ) - } - break; - - case 14: - { - RADIO_TEST__( mm_radio_scan_stop(g_my_radio); ) - } - break; - - default: - break; - } -} - -int main(int argc, char **argv) -{ - while(1) - { - char key = 0; - int choosen = 0; - - choosen = __menu(); - - if ( choosen == -1) - continue; - - if ( choosen == 0 ) - break; - - __call_api( choosen ); - } -} - - * @endcode */ int mm_radio_set_frequency(MMHandleType hradio, int freq); @@ -2301,441 +268,29 @@ int mm_radio_set_frequency(MMHandleType hradio, int freq); * @remark None * @see mm_radio_set_frequency * @par Example - * @code -#include -#include -#include - -#define RADIO_TEST__(x_test) \ - ret = x_test \ - if ( ! ret ) \ - { \ - printf("PASS : %s -- %s:%d\n", #x_test, __FILE__, __LINE__); \ - } \ - else \ - { \ - printf("FAIL : %s ERR-CODE : %d -- %s:%d\n", #x_test, ret, __FILE__, __LINE__); \ - } - -static MMHandleType g_my_radio = 0; - -int __menu(void) -{ - int menu_item = 0; - - printf("---------------------------------------------------------\n"); - printf("mm-radio rt api test. try now!\n"); - printf("---------------------------------------------------------\n"); - printf("[1] mm_radio_create\n"); - printf("[2] mm_radio_destroy\n"); - printf("[3] mm_radio_realize\n"); - printf("[4] mm_radio_unrealize\n"); - printf("[7] mm_radio_get_state\n"); - printf("[8] mm_radio_start\n"); - printf("[9] mm_radio_stop\n"); - printf("[10] mm_radio_seek\n"); - printf("[11] mm_radio_set_frequency\n"); - printf("[12] mm_radio_get_frequency\n"); - printf("[13] mm_radio_scan_start\n"); - printf("[14] mm_radio_scan_stop\n"); - printf("[0] quit\n"); - printf("---------------------------------------------------------\n"); - printf("choose one : "); - scanf("%d", &menu_item); - - if ( menu_item > 15 ) - menu_item = -1; - - return menu_item; -} - -int __msg_rt_callback(int message, void *pParam, void *user_param) -{ - MMMessageParamType* param = (MMMessageParamType*)pParam; - int ret = 0; - - printf("incomming message : %d\n", message); - - switch(message) - { - case MM_MESSAGE_STATE_CHANGED: - - printf("MM_MESSAGE_STATE_CHANGED: current : %d old : %d\n" - , param->state.current, param->state.previous); - break; - case MM_MESSAGE_RADIO_SCAN_START: - printf("MM_MESSAGE_RADIO_SCAN_START\n"); - break; - case MM_MESSAGE_RADIO_SCAN_INFO: - assert(param); - printf("MM_MESSAGE_RADIO_SCAN_INFO : freq : %d\n", param->radio_scan.frequency); - break; - case MM_MESSAGE_RADIO_SCAN_STOP: - printf("MM_MESSAGE_RADIO_SCAN_STOP\n"); - break; - case MM_MESSAGE_RADIO_SCAN_FINISH: - printf("MM_MESSAGE_RADIO_SCAN_FINISHED\n"); - break; - case MM_MESSAGE_RADIO_SEEK_START: - printf("MM_MESSAGE_RADIO_SEEK_START\n"); - break; - case MM_MESSAGE_RADIO_SEEK_FINISH: - printf("MM_MESSAGE_RADIO_SEEK_FINISHED : freq : %d\n", param->radio_scan.frequency); - break; - default: - printf("ERROR : unknown message received!\n"); - break; - } - - return true; -} - -void __call_api( int choosen ) -{ - int ret = MM_ERROR_NONE; - - switch( choosen ) - { - case 1: - { - RADIO_TEST__( mm_radio_create( &g_my_radio ); ) - RADIO_TEST__( mm_radio_set_message_callback( g_my_radio, __msg_rt_callback, &g_my_radio); ) - } - break; - - case 2: - { - RADIO_TEST__( mm_radio_destroy( g_my_radio ); ) - g_my_radio = 0; - } - break; - - case 3: - { - RADIO_TEST__( mm_radio_realize(g_my_radio ); ) - } - break; - - case 4: - { - RADIO_TEST__( mm_radio_unrealize(g_my_radio ); ) - } - break; - - case 7: - { - MMRadioStateType state = 0; - RADIO_TEST__( mm_radio_get_state(g_my_radio, &state); ) - - printf("state : %d\n", state); - } - break; - - case 8: - { - RADIO_TEST__( mm_radio_start(g_my_radio); ) - } - break; - - case 9: - { - RADIO_TEST__( mm_radio_stop(g_my_radio); ) - } - break; - - case 10: - { - MMRadioSeekDirectionType direction = 0; - printf("input seek direction(0:UP/1:DOWN) : "); - scanf("%d", &direction); - RADIO_TEST__( mm_radio_seek(g_my_radio, direction); ) - } - break; - - case 11: - { - int freq = 0; - printf("input freq : "); - scanf("%d", &freq); - RADIO_TEST__( mm_radio_set_frequency(g_my_radio, freq); ) - } - break; - - case 12: - { - int freq = 0; - RADIO_TEST__( mm_radio_get_frequency(g_my_radio, &freq ); ) - - printf("freq : %d\n", freq); - } - break; - - case 13: - { - RADIO_TEST__( mm_radio_scan_start(g_my_radio); ) - } - break; - - case 14: - { - RADIO_TEST__( mm_radio_scan_stop(g_my_radio); ) - } - break; - - default: - break; - } -} - -int main(int argc, char **argv) -{ - while(1) - { - char key = 0; - int choosen = 0; - - choosen = __menu(); - - if ( choosen == -1) - continue; - - if ( choosen == 0 ) - break; - - __call_api( choosen ); - } -} - - * @endcode */ -int mm_radio_get_frequency(MMHandleType hradio, int* pFreq); +int mm_radio_get_frequency(MMHandleType hradio, int *pFreq); /** * This function is to start for getting all effective frequencies. \n - * So, if a frequency is found, MM_MESSAGE_RADIO_SCAN_INFO will be posted with frequency information. - * If there is no frequency, we will post MM_MESSAGE_RADIO_SCAN_FINISH. - * And then, the radio state will be changed as MM_RADIO_STATE_READY. + * So, if a frequency is found, MM_MESSAGE_RADIO_SCAN_INFO will be posted with frequency information. + * If there is no frequency, we will post MM_MESSAGE_RADIO_SCAN_FINISH. + * And then, the radio state will be changed as MM_RADIO_STATE_READY. * * @param hradio [in] Handle of radio. * * @return This function returns zero on success, or negative value with errors * @pre MM_RADIO_STATE_READY - * @post MM_RADIO_STATE_SCANNING + * @post MM_RADIO_STATE_SCANNING * @remark None * @see mm_radio_scan_stop * @par Example - * @code -#include -#include -#include - -#define RADIO_TEST__(x_test) \ - ret = x_test \ - if ( ! ret ) \ - { \ - printf("PASS : %s -- %s:%d\n", #x_test, __FILE__, __LINE__); \ - } \ - else \ - { \ - printf("FAIL : %s ERR-CODE : %d -- %s:%d\n", #x_test, ret, __FILE__, __LINE__); \ - } - -static MMHandleType g_my_radio = 0; - -int __menu(void) -{ - int menu_item = 0; - - printf("---------------------------------------------------------\n"); - printf("mm-radio rt api test. try now!\n"); - printf("---------------------------------------------------------\n"); - printf("[1] mm_radio_create\n"); - printf("[2] mm_radio_destroy\n"); - printf("[3] mm_radio_realize\n"); - printf("[4] mm_radio_unrealize\n"); - printf("[7] mm_radio_get_state\n"); - printf("[8] mm_radio_start\n"); - printf("[9] mm_radio_stop\n"); - printf("[10] mm_radio_seek\n"); - printf("[11] mm_radio_set_frequency\n"); - printf("[12] mm_radio_get_frequency\n"); - printf("[13] mm_radio_scan_start\n"); - printf("[14] mm_radio_scan_stop\n"); - printf("[0] quit\n"); - printf("---------------------------------------------------------\n"); - printf("choose one : "); - scanf("%d", &menu_item); - - if ( menu_item > 15 ) - menu_item = -1; - - return menu_item; -} - -int __msg_rt_callback(int message, void *pParam, void *user_param) -{ - MMMessageParamType* param = (MMMessageParamType*)pParam; - int ret = 0; - - printf("incomming message : %d\n", message); - - switch(message) - { - case MM_MESSAGE_STATE_CHANGED: - - printf("MM_MESSAGE_STATE_CHANGED: current : %d old : %d\n" - , param->state.current, param->state.previous); - break; - case MM_MESSAGE_RADIO_SCAN_START: - printf("MM_MESSAGE_RADIO_SCAN_START\n"); - break; - case MM_MESSAGE_RADIO_SCAN_INFO: - assert(param); - printf("MM_MESSAGE_RADIO_SCAN_INFO : freq : %d\n", param->radio_scan.frequency); - break; - case MM_MESSAGE_RADIO_SCAN_STOP: - printf("MM_MESSAGE_RADIO_SCAN_STOP\n"); - break; - case MM_MESSAGE_RADIO_SCAN_FINISH: - printf("MM_MESSAGE_RADIO_SCAN_FINISHED\n"); - break; - case MM_MESSAGE_RADIO_SEEK_START: - printf("MM_MESSAGE_RADIO_SEEK_START\n"); - break; - case MM_MESSAGE_RADIO_SEEK_FINISH: - printf("MM_MESSAGE_RADIO_SEEK_FINISHED : freq : %d\n", param->radio_scan.frequency); - break; - default: - printf("ERROR : unknown message received!\n"); - break; - } - - return true; -} - -void __call_api( int choosen ) -{ - int ret = MM_ERROR_NONE; - - switch( choosen ) - { - case 1: - { - RADIO_TEST__( mm_radio_create( &g_my_radio ); ) - RADIO_TEST__( mm_radio_set_message_callback( g_my_radio, __msg_rt_callback, &g_my_radio); ) - } - break; - - case 2: - { - RADIO_TEST__( mm_radio_destroy( g_my_radio ); ) - g_my_radio = 0; - } - break; - - case 3: - { - RADIO_TEST__( mm_radio_realize(g_my_radio ); ) - } - break; - - case 4: - { - RADIO_TEST__( mm_radio_unrealize(g_my_radio ); ) - } - break; - - case 7: - { - MMRadioStateType state = 0; - RADIO_TEST__( mm_radio_get_state(g_my_radio, &state); ) - - printf("state : %d\n", state); - } - break; - - case 8: - { - RADIO_TEST__( mm_radio_start(g_my_radio); ) - } - break; - - case 9: - { - RADIO_TEST__( mm_radio_stop(g_my_radio); ) - } - break; - - case 10: - { - MMRadioSeekDirectionType direction = 0; - printf("input seek direction(0:UP/1:DOWN) : "); - scanf("%d", &direction); - RADIO_TEST__( mm_radio_seek(g_my_radio, direction); ) - } - break; - - case 11: - { - int freq = 0; - printf("input freq : "); - scanf("%d", &freq); - RADIO_TEST__( mm_radio_set_frequency(g_my_radio, freq); ) - } - break; - - case 12: - { - int freq = 0; - RADIO_TEST__( mm_radio_get_frequency(g_my_radio, &freq ); ) - - printf("freq : %d\n", freq); - } - break; - - case 13: - { - RADIO_TEST__( mm_radio_scan_start(g_my_radio); ) - } - break; - - case 14: - { - RADIO_TEST__( mm_radio_scan_stop(g_my_radio); ) - } - break; - - default: - break; - } -} - -int main(int argc, char **argv) -{ - while(1) - { - char key = 0; - int choosen = 0; - - choosen = __menu(); - - if ( choosen == -1) - continue; - - if ( choosen == 0 ) - break; - - __call_api( choosen ); - } -} - - * @endcode */ int mm_radio_scan_start(MMHandleType hradio); /** * This function is to stop for getting all the effective frequencies. \n - * So, application can use this API to stop in the middle of scanning. + * So, application can use this API to stop in the middle of scanning. * * @param hradio [in] Handle of radio. * @@ -2745,212 +300,6 @@ int mm_radio_scan_start(MMHandleType hradio); * @remark None * @see mm_radio_scan_start * @par Example - * @code -#include -#include -#include - -#define RADIO_TEST__(x_test) \ - ret = x_test \ - if ( ! ret ) \ - { \ - printf("PASS : %s -- %s:%d\n", #x_test, __FILE__, __LINE__); \ - } \ - else \ - { \ - printf("FAIL : %s ERR-CODE : %d -- %s:%d\n", #x_test, ret, __FILE__, __LINE__); \ - } - -static MMHandleType g_my_radio = 0; - -int __menu(void) -{ - int menu_item = 0; - - printf("---------------------------------------------------------\n"); - printf("mm-radio rt api test. try now!\n"); - printf("---------------------------------------------------------\n"); - printf("[1] mm_radio_create\n"); - printf("[2] mm_radio_destroy\n"); - printf("[3] mm_radio_realize\n"); - printf("[4] mm_radio_unrealize\n"); - printf("[7] mm_radio_get_state\n"); - printf("[8] mm_radio_start\n"); - printf("[9] mm_radio_stop\n"); - printf("[10] mm_radio_seek\n"); - printf("[11] mm_radio_set_frequency\n"); - printf("[12] mm_radio_get_frequency\n"); - printf("[13] mm_radio_scan_start\n"); - printf("[14] mm_radio_scan_stop\n"); - printf("[0] quit\n"); - printf("---------------------------------------------------------\n"); - printf("choose one : "); - scanf("%d", &menu_item); - - if ( menu_item > 15 ) - menu_item = -1; - - return menu_item; -} - -int __msg_rt_callback(int message, void *pParam, void *user_param) -{ - MMMessageParamType* param = (MMMessageParamType*)pParam; - int ret = 0; - - printf("incomming message : %d\n", message); - - switch(message) - { - case MM_MESSAGE_STATE_CHANGED: - - printf("MM_MESSAGE_STATE_CHANGED: current : %d old : %d\n" - , param->state.current, param->state.previous); - break; - case MM_MESSAGE_RADIO_SCAN_START: - printf("MM_MESSAGE_RADIO_SCAN_START\n"); - break; - case MM_MESSAGE_RADIO_SCAN_INFO: - assert(param); - printf("MM_MESSAGE_RADIO_SCAN_INFO : freq : %d\n", param->radio_scan.frequency); - break; - case MM_MESSAGE_RADIO_SCAN_STOP: - printf("MM_MESSAGE_RADIO_SCAN_STOP\n"); - break; - case MM_MESSAGE_RADIO_SCAN_FINISH: - printf("MM_MESSAGE_RADIO_SCAN_FINISHED\n"); - break; - case MM_MESSAGE_RADIO_SEEK_START: - printf("MM_MESSAGE_RADIO_SEEK_START\n"); - break; - case MM_MESSAGE_RADIO_SEEK_FINISH: - printf("MM_MESSAGE_RADIO_SEEK_FINISHED : freq : %d\n", param->radio_scan.frequency); - break; - default: - printf("ERROR : unknown message received!\n"); - break; - } - - return true; -} - -void __call_api( int choosen ) -{ - int ret = MM_ERROR_NONE; - - switch( choosen ) - { - case 1: - { - RADIO_TEST__( mm_radio_create( &g_my_radio ); ) - RADIO_TEST__( mm_radio_set_message_callback( g_my_radio, __msg_rt_callback, &g_my_radio); ) - } - break; - - case 2: - { - RADIO_TEST__( mm_radio_destroy( g_my_radio ); ) - g_my_radio = 0; - } - break; - - case 3: - { - RADIO_TEST__( mm_radio_realize(g_my_radio ); ) - } - break; - - case 4: - { - RADIO_TEST__( mm_radio_unrealize(g_my_radio ); ) - } - break; - - case 7: - { - MMRadioStateType state = 0; - RADIO_TEST__( mm_radio_get_state(g_my_radio, &state); ) - - printf("state : %d\n", state); - } - break; - - case 8: - { - RADIO_TEST__( mm_radio_start(g_my_radio); ) - } - break; - - case 9: - { - RADIO_TEST__( mm_radio_stop(g_my_radio); ) - } - break; - - case 10: - { - MMRadioSeekDirectionType direction = 0; - printf("input seek direction(0:UP/1:DOWN) : "); - scanf("%d", &direction); - RADIO_TEST__( mm_radio_seek(g_my_radio, direction); ) - } - break; - - case 11: - { - int freq = 0; - printf("input freq : "); - scanf("%d", &freq); - RADIO_TEST__( mm_radio_set_frequency(g_my_radio, freq); ) - } - break; - - case 12: - { - int freq = 0; - RADIO_TEST__( mm_radio_get_frequency(g_my_radio, &freq ); ) - - printf("freq : %d\n", freq); - } - break; - - case 13: - { - RADIO_TEST__( mm_radio_scan_start(g_my_radio); ) - } - break; - - case 14: - { - RADIO_TEST__( mm_radio_scan_stop(g_my_radio); ) - } - break; - - default: - break; - } -} - -int main(int argc, char **argv) -{ - while(1) - { - char key = 0; - int choosen = 0; - - choosen = __menu(); - - if ( choosen == -1) - continue; - - if ( choosen == 0 ) - break; - - __call_api( choosen ); - } -} - - * @endcode */ int mm_radio_scan_stop(MMHandleType hradio); @@ -2964,223 +313,8 @@ int mm_radio_scan_stop(MMHandleType hradio); * @pre None * @post None * @remark None - * @see + * @see * @par Example - * @code -#include -#include -#include - -#define RADIO_TEST__(x_test) \ - ret = x_test \ - if ( ! ret ) \ - { \ - printf("PASS : %s -- %s:%d\n", #x_test, __FILE__, __LINE__); \ - } \ - else \ - { \ - printf("FAIL : %s ERR-CODE : %d -- %s:%d\n", #x_test, ret, __FILE__, __LINE__); \ - } - -static MMHandleType g_my_radio = 0; - -int __menu(void) -{ - int menu_item = 0; - - printf("---------------------------------------------------------\n"); - printf("mm-radio rt api test. try now!\n"); - printf("---------------------------------------------------------\n"); - printf("[1] mm_radio_create\n"); - printf("[2] mm_radio_destroy\n"); - printf("[3] mm_radio_realize\n"); - printf("[4] mm_radio_unrealize\n"); - printf("[7] mm_radio_get_state\n"); - printf("[8] mm_radio_start\n"); - printf("[9] mm_radio_stop\n"); - printf("[10] mm_radio_seek\n"); - printf("[11] mm_radio_set_frequency\n"); - printf("[12] mm_radio_get_frequency\n"); - printf("[13] mm_radio_scan_start\n"); - printf("[14] mm_radio_scan_stop\n"); - printf("[16] mm_radio_set_mute\n"); - printf("[0] quit\n"); - printf("---------------------------------------------------------\n"); - printf("choose one : "); - scanf("%d", &menu_item); - - if ( menu_item > 16 ) - menu_item = -1; - - return menu_item; -} - -int __msg_rt_callback(int message, void *pParam, void *user_param) -{ - MMMessageParamType* param = (MMMessageParamType*)pParam; - int ret = 0; - - printf("incomming message : %d\n", message); - - switch(message) - { - case MM_MESSAGE_STATE_CHANGED: - - printf("MM_MESSAGE_STATE_CHANGED: current : %d old : %d\n" - , param->state.current, param->state.previous); - break; - case MM_MESSAGE_RADIO_SCAN_START: - printf("MM_MESSAGE_RADIO_SCAN_START\n"); - break; - case MM_MESSAGE_RADIO_SCAN_INFO: - assert(param); - printf("MM_MESSAGE_RADIO_SCAN_INFO : freq : %d\n", param->radio_scan.frequency); - break; - case MM_MESSAGE_RADIO_SCAN_STOP: - printf("MM_MESSAGE_RADIO_SCAN_STOP\n"); - break; - case MM_MESSAGE_RADIO_SCAN_FINISH: - printf("MM_MESSAGE_RADIO_SCAN_FINISHED\n"); - break; - case MM_MESSAGE_RADIO_SEEK_START: - printf("MM_MESSAGE_RADIO_SEEK_START\n"); - break; - case MM_MESSAGE_RADIO_SEEK_FINISH: - printf("MM_MESSAGE_RADIO_SEEK_FINISHED : freq : %d\n", param->radio_scan.frequency); - break; - default: - printf("ERROR : unknown message received!\n"); - break; - } - - return true; -} - -void __call_api( int choosen ) -{ - int ret = MM_ERROR_NONE; - - switch( choosen ) - { - case 1: - { - RADIO_TEST__( mm_radio_create( &g_my_radio ); ) - RADIO_TEST__( mm_radio_set_message_callback( g_my_radio, __msg_rt_callback, &g_my_radio); ) - } - break; - - case 2: - { - RADIO_TEST__( mm_radio_destroy( g_my_radio ); ) - g_my_radio = 0; - } - break; - - case 3: - { - RADIO_TEST__( mm_radio_realize(g_my_radio ); ) - } - break; - - case 4: - { - RADIO_TEST__( mm_radio_unrealize(g_my_radio ); ) - } - break; - - case 7: - { - MMRadioStateType state = 0; - RADIO_TEST__( mm_radio_get_state(g_my_radio, &state); ) - - printf("state : %d\n", state); - } - break; - - case 8: - { - RADIO_TEST__( mm_radio_start(g_my_radio); ) - } - break; - - case 9: - { - RADIO_TEST__( mm_radio_stop(g_my_radio); ) - } - break; - - case 10: - { - MMRadioSeekDirectionType direction = 0; - printf("input seek direction(0:UP/1:DOWN) : "); - scanf("%d", &direction); - RADIO_TEST__( mm_radio_seek(g_my_radio, direction); ) - } - break; - - case 11: - { - int freq = 0; - printf("input freq : "); - scanf("%d", &freq); - RADIO_TEST__( mm_radio_set_frequency(g_my_radio, freq); ) - } - break; - - case 12: - { - int freq = 0; - RADIO_TEST__( mm_radio_get_frequency(g_my_radio, &freq ); ) - - printf("freq : %d\n", freq); - } - break; - - case 13: - { - RADIO_TEST__( mm_radio_scan_start(g_my_radio); ) - } - break; - - case 14: - { - RADIO_TEST__( mm_radio_scan_stop(g_my_radio); ) - } - break; - - case 16: - { - bool muted = 0; - printf("select one(0:UNMUTE/1:MUTE) : "); - scanf("%d", &muted); - RADIO_TEST__( mm_radio_set_mute(g_my_radio, muted); ) - } - - default: - break; - } -} - -int main(int argc, char **argv) -{ - while(1) - { - char key = 0; - int choosen = 0; - - choosen = __menu(); - - if ( choosen == -1) - continue; - - if ( choosen == 0 ) - break; - - __call_api( choosen ); - } -} - - * @endcode */ int mm_radio_set_mute(MMHandleType hradio, bool muted); /** @@ -3195,221 +329,6 @@ int mm_radio_set_mute(MMHandleType hradio, bool muted); * @remark None * @see * @par Example - * @code -#include -#include -#include - -#define RADIO_TEST__(x_test) \ - ret = x_test \ - if ( ! ret ) \ - { \ - printf("PASS : %s -- %s:%d\n", #x_test, __FILE__, __LINE__); \ - } \ - else \ - { \ - printf("FAIL : %s ERR-CODE : %d -- %s:%d\n", #x_test, ret, __FILE__, __LINE__); \ - } - -static MMHandleType g_my_radio = 0; - -int __menu(void) -{ - int menu_item = 0; - - printf("---------------------------------------------------------\n"); - printf("mm-radio rt api test. try now!\n"); - printf("---------------------------------------------------------\n"); - printf("[1] mm_radio_create\n"); - printf("[2] mm_radio_destroy\n"); - printf("[3] mm_radio_realize\n"); - printf("[4] mm_radio_unrealize\n"); - printf("[7] mm_radio_get_state\n"); - printf("[8] mm_radio_start\n"); - printf("[9] mm_radio_stop\n"); - printf("[10] mm_radio_seek\n"); - printf("[11] mm_radio_set_frequency\n"); - printf("[12] mm_radio_get_frequency\n"); - printf("[13] mm_radio_scan_start\n"); - printf("[14] mm_radio_scan_stop\n"); - printf("[16] mm_radio_set_mute\n"); - printf("[0] quit\n"); - printf("---------------------------------------------------------\n"); - printf("choose one : "); - scanf("%d", &menu_item); - - if ( menu_item > 16 ) - menu_item = -1; - - return menu_item; -} - -int __msg_rt_callback(int message, void *pParam, void *user_param) -{ - MMMessageParamType* param = (MMMessageParamType*)pParam; - int ret = 0; - - printf("incomming message : %d\n", message); - - switch(message) - { - case MM_MESSAGE_STATE_CHANGED: - - printf("MM_MESSAGE_STATE_CHANGED: current : %d old : %d\n" - , param->state.current, param->state.previous); - break; - case MM_MESSAGE_RADIO_SCAN_START: - printf("MM_MESSAGE_RADIO_SCAN_START\n"); - break; - case MM_MESSAGE_RADIO_SCAN_INFO: - assert(param); - printf("MM_MESSAGE_RADIO_SCAN_INFO : freq : %d\n", param->radio_scan.frequency); - break; - case MM_MESSAGE_RADIO_SCAN_STOP: - printf("MM_MESSAGE_RADIO_SCAN_STOP\n"); - break; - case MM_MESSAGE_RADIO_SCAN_FINISH: - printf("MM_MESSAGE_RADIO_SCAN_FINISHED\n"); - break; - case MM_MESSAGE_RADIO_SEEK_START: - printf("MM_MESSAGE_RADIO_SEEK_START\n"); - break; - case MM_MESSAGE_RADIO_SEEK_FINISH: - printf("MM_MESSAGE_RADIO_SEEK_FINISHED : freq : %d\n", param->radio_scan.frequency); - break; - default: - printf("ERROR : unknown message received!\n"); - break; - } - - return true; -} - -void __call_api( int choosen ) -{ - int ret = MM_ERROR_NONE; - - switch( choosen ) - { - case 1: - { - RADIO_TEST__( mm_radio_create( &g_my_radio ); ) - RADIO_TEST__( mm_radio_set_message_callback( g_my_radio, __msg_rt_callback, &g_my_radio); ) - } - break; - - case 2: - { - RADIO_TEST__( mm_radio_destroy( g_my_radio ); ) - g_my_radio = 0; - } - break; - - case 3: - { - RADIO_TEST__( mm_radio_realize(g_my_radio ); ) - } - break; - - case 4: - { - RADIO_TEST__( mm_radio_unrealize(g_my_radio ); ) - } - break; - - case 7: - { - MMRadioStateType state = 0; - RADIO_TEST__( mm_radio_get_state(g_my_radio, &state); ) - - printf("state : %d\n", state); - } - break; - - case 8: - { - RADIO_TEST__( mm_radio_start(g_my_radio); ) - } - break; - - case 9: - { - RADIO_TEST__( mm_radio_stop(g_my_radio); ) - } - break; - - case 10: - { - MMRadioSeekDirectionType direction = 0; - printf("input seek direction(0:UP/1:DOWN) : "); - scanf("%d", &direction); - RADIO_TEST__( mm_radio_seek(g_my_radio, direction); ) - } - break; - - case 11: - { - int freq = 0; - printf("input freq : "); - scanf("%d", &freq); - RADIO_TEST__( mm_radio_set_frequency(g_my_radio, freq); ) - } - break; - - case 12: - { - int freq = 0; - RADIO_TEST__( mm_radio_get_frequency(g_my_radio, &freq ); ) - - printf("freq : %d\n", freq); - } - break; - - case 13: - { - RADIO_TEST__( mm_radio_scan_start(g_my_radio); ) - } - break; - - case 14: - { - RADIO_TEST__( mm_radio_scan_stop(g_my_radio); ) - } - break; - - case 16: - { - bool muted = 0; - printf("select one(0:UNMUTE/1:MUTE) : "); - scanf("%d", &muted); - RADIO_TEST__( mm_radio_set_mute(g_my_radio, muted); ) - } - - default: - break; - } -} - -int main(int argc, char **argv) -{ - while(1) - { - char key = 0; - int choosen = 0; - - choosen = __menu(); - - if ( choosen == -1) - continue; - - if ( choosen == 0 ) - break; - - __call_api( choosen ); - } -} - - * @endcode */ int mm_radio_get_signal_strength(MMHandleType hradio, int *value); @@ -3443,12 +362,26 @@ int mm_radio_get_region_type(MMHandleType hradio, MMRadioRegionType *type); int mm_radio_get_region_frequency_range(MMHandleType hradio, unsigned int *min, unsigned int *max); /** + * This function is to get channel spacing. + * + * @param hradio [in] Handle of radio. + * @param channel_spacing [out] channel spacing value + * + * @return This function returns zero on success, or negative value with errors + * @pre None + * @post None + * @see mm_radio_get_region_type() + */ +int mm_radio_get_channel_spacing(MMHandleType hradio, int *channel_spacing); + + +/** @} */ - + #ifdef __cplusplus - } +} #endif #endif /* __MM_RADIO_H__ */ diff --git a/src/include/mm_radio_asm.h b/src/include/mm_radio_asm.h index c8d1c93..83efad6 100644 --- a/src/include/mm_radio_asm.h +++ b/src/include/mm_radio_asm.h @@ -18,7 +18,7 @@ * limitations under the License. * */ - + #ifndef MM_RADIO_ASM_H_ #define MM_RADIO_ASM_H_ @@ -34,6 +34,8 @@ enum { MMRADIO_ASM_CB_POSTMSG, MMRADIO_ASM_CB_SKIP_POSTMSG }; + + typedef struct { int handle; int pid; @@ -42,9 +44,19 @@ typedef struct { ASM_sound_states_t state; } MMRadioASM; +typedef struct { + int handle; + int pid; + int by_asm_cb; + int event_src; + int sound_focus_register; + int asm_session_flags; +} MMRadioAudioFocus; + + /* returns allocated handle */ -int mmradio_asm_register(MMRadioASM* sm, ASM_sound_cb_t callback, void* param); -int mmradio_asm_deregister(MMRadioASM* sm); -int mmradio_asm_set_state(MMRadioASM* sm, ASM_sound_states_t state, ASM_resource_t resource); +int mmradio_asm_register(MMRadioASM *sm, ASM_sound_cb_t callback, void *param); +int mmradio_asm_deregister(MMRadioASM *sm); +int mmradio_asm_set_state(MMRadioASM *sm, ASM_sound_states_t state, ASM_resource_t resource); #endif /* MM_RADIO_ASM_H_ */ diff --git a/src/include/mm_radio_priv.h b/src/include/mm_radio_priv.h index 349db4f..0f0c0e7 100644 --- a/src/include/mm_radio_priv.h +++ b/src/include/mm_radio_priv.h @@ -44,7 +44,7 @@ #include #ifdef __cplusplus - extern "C" { +extern "C" { #endif /*=========================================================================================== @@ -94,11 +94,10 @@ typedef enum MMRADIO_COMMAND_SET_REGION, MMRADIO_COMMAND_GET_REGION, MMRADIO_COMMAND_NUM -} MMRadioCommand; +}MMRadioCommand; /* max and mix frequency types, KHz */ -typedef enum -{ +typedef enum { MM_RADIO_FREQ_NONE = 0, /* min band types */ MM_RADIO_FREQ_MIN_76100_KHZ = 76100, @@ -107,25 +106,23 @@ typedef enum /* max band types */ MM_RADIO_FREQ_MAX_89900_KHZ = 89900, MM_RADIO_FREQ_MAX_108000_KHZ = 108000, -}MMRadioFreqTypes; +} MMRadioFreqTypes; /* de-emphasis types */ -typedef enum -{ +typedef enum { MM_RADIO_DEEMPHASIS_NONE = 0, MM_RADIO_DEEMPHASIS_50_US, MM_RADIO_DEEMPHASIS_75_US, -}MMRadioDeemphasis; +} MMRadioDeemphasis; /* radio region settings */ -typedef struct -{ +typedef struct { MMRadioRegionType country; - MMRadioDeemphasis deemphasis; // unit : us - MMRadioFreqTypes band_min; // <- freq. range, unit : KHz - MMRadioFreqTypes band_max; // -> - //int channel_spacing; // TBD -}MMRadioRegion_t; + MMRadioDeemphasis deemphasis; /* unit : us */ + MMRadioFreqTypes band_min; /* <- freq. range, unit : KHz */ + MMRadioFreqTypes band_max; /* -> */ + int channel_spacing; /* TBD */ +} MMRadioRegion_t; /*--------------------------------------------------------------------------- GLOBAL DATA TYPE DEFINITIONS: @@ -133,14 +130,13 @@ typedef struct #define USE_GST_PIPELINE #ifdef USE_GST_PIPELINE -typedef struct _mm_radio_gstreamer_s -{ +typedef struct _mm_radio_gstreamer_s { GMainLoop *loop; GstElement *pipeline; - GstElement *avsysaudiosrc; + GstElement *audiosrc; GstElement *queue2; GstElement *volume; - GstElement *avsysaudiosink; + GstElement *audiosink; GstBuffer *output_buffer; } mm_radio_gstreamer_s; #endif @@ -157,11 +153,11 @@ typedef struct { pthread_mutex_t cmd_lock; /* radio attributes */ - MMHandleType* attrs; + MMHandleType *attrs; /* message callback */ MMMessageCallback msg_cb; - void* msg_cb_param; + void *msg_cb_param; /* radio device fd */ int radio_fd; @@ -185,11 +181,15 @@ typedef struct { MMRadioSeekDirectionType seek_direction; /* ASM */ +#ifdef FEATURE_ASM_SUPPORT MMRadioASM sm; +#else + MMRadioAudioFocus sm; +#endif int freq; #ifdef USE_GST_PIPELINE - mm_radio_gstreamer_s* pGstreamer_s; + mm_radio_gstreamer_s *pGstreamer_s; #endif /* region settings */ @@ -199,38 +199,38 @@ typedef struct { /*=========================================================================================== 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_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); #ifdef USE_GST_PIPELINE -int _mmradio_realize_pipeline( mm_radio_t* radio); -int _mmradio_start_pipeline(mm_radio_t* radio); -int _mmradio_stop_pipeline( mm_radio_t* radio); -int _mmradio_destroy_pipeline(mm_radio_t* radio); +int _mmradio_realize_pipeline(mm_radio_t *radio); +int _mmradio_start_pipeline(mm_radio_t *radio); +int _mmradio_stop_pipeline(mm_radio_t *radio); +int _mmradio_destroy_pipeline(mm_radio_t *radio); #endif -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, uint *min_freq, uint *max_freq); +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); #if 0 -int mmradio_set_attrs(mm_radio_t* radio, MMRadioAttrsType type, MMHandleType attrs); -MMHandleType mmradio_get_attrs(mm_radio_t* radio, MMRadioAttrsType type); +int mmradio_set_attrs(mm_radio_t *radio, MMRadioAttrsType type, MMHandleType attrs); +MMHandleType mmradio_get_attrs(mm_radio_t *radio, MMRadioAttrsType type); #endif #ifdef __cplusplus - } +} #endif #endif /* __MM_Radio_INTERNAL_H__ */ diff --git a/src/include/mm_radio_priv_common.h b/src/include/mm_radio_priv_common.h new file mode 100755 index 0000000..c5f6f3a --- /dev/null +++ b/src/include/mm_radio_priv_common.h @@ -0,0 +1,324 @@ +/* + * libmm-radio + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: JongHyuk Choi , YoungHwan An + * + * 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_COMMON_H__ +#define __MM_Radio_INTERNAL_COMMON_H__ + +/*=========================================================================================== + INCLUDE FILES +========================================================================================== */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "mm_radio_asm.h" +#include "mm_radio.h" +#include "mm_radio_utils.h" + + +#include +#include + +/*compile #include */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define MM_RADIO_TRUE 1 +#define MM_RADIO_FALSE 0 +/*--------------------------------------------------------------------------- + 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_TUNE, + MMRADIO_COMMAND_RDS_START, + MMRADIO_COMMAND_RDS_STOP, + MMRADIO_COMMAND_NUM +}MMRadioCommand; + + +#define MMFW_RADIO_TUNING_DEFUALT_FILE "/usr/etc/mmfw_fmradio.ini" +#define MMFW_RADIO_TUNING_TEMP_FILE "/opt/usr/media/.mmfw_fmradio.ini" +#define MMFW_RADIO_TUNING_ENABLE "tuning:enable" + +#define MMFW_RADIO_TUNING_SNR_THR "fmradio:mmfw_fmradio_snr_threshold" +#define MMFW_RADIO_TUNING_RSSI_THR "fmradio:mmfw_fmradio_rssi_threshold" +#define MMFW_RADIO_TUNING_CNT_THR "fmradio:mmfw_fmradio_cnt_threshold" + +/*Soft Mute*/ +#define MMFW_RADIO_TUNING_SOFT_MUTE_START_SNR "fmradio:mmfw_fmradio_softmute_start_snr" +#define MMFW_RADIO_TUNING_SOFT_MUTE_STOP_SNR "fmradio:mmfw_fmradio_softmute_stop_snr" +#define MMFW_RADIO_TUNING_SOFT_MUTE_START_RSSI "fmradio:mmfw_fmradio_softmute_start_rssi" +#define MMFW_RADIO_TUNING_SOFT_MUTE_STOP_RSSI "fmradio:mmfw_fmradio_softmute_stop_rssi" +#define MMFW_RADIO_TUNING_SOFT_MUTE_START_MUTE "fmradio:mmfw_fmradio_softmute_start_mute" +#define MMFW_RADIO_TUNING_SOFT_MUTE_STOP_ATTEN "fmradio:mmfw_fmradio_softmute_stop_atten" +#define MMFW_RADIO_TUNING_SOFT_MUTE_MUTE_RATE "fmradio:mmfw_fmradio_softmute_mute_rate" +#define MMFW_RADIO_TUNING_SOFT_MUTE_SNR40 "fmradio:mmfw_fmradio_softmute_snr40" + +/* sprd sc2331 */ +#define MMFW_RADIO_TUNING_FREQUENCY_OFFSET "fmradio:mmfw_fmradio_frequency_offset" +#define MMFW_RADIO_TUNING_NOISE_POWER "fmradio:mmfw_fmradio_noise_power" +#define MMFW_RADIO_TUNING_PILOT_POWER "fmradio:mmfw_fmradio_pilot_power" +#define MMFW_RADIO_TUNING_SOFTMUTE_ENABLE "fmradio:mmfw_fmradio_softmute_enable" + +#define MMFW_RADIO_TUNING_VOLUME_LEVELS "fmradio:volume_levels" +#define MMFW_RADIO_TUNING_VOLUME_TABLE "fmradio:volume_table" +#define MMFW_RADIO_TUNING_VOLUME_STEPS 16 + +#define RECORDING_VOLUME_LOWER_THRESHOLD 5 +#define RECORDING_VOLUME_HEIGHER_THRESHOLD 11 + +/* 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; + +typedef enum { + MMRADIO_EVENT_DESTROY = 0, + MMRADIO_EVENT_STOP = 1, + MMRADIO_EVENT_SET_FREQ_ASYNC = 2, + MMRADIO_EVENT_NUM +} MMRadioEvent; + +/*--------------------------------------------------------------------------- + GLOBAL DATA TYPE DEFINITIONS: +---------------------------------------------------------------------------*/ +/*#define USE_GST_PIPELINE */ + +#ifdef USE_GST_PIPELINE +typedef struct _mm_radio_gstreamer_s { + GMainLoop *loop; + GstElement *pipeline; + GstElement *avsysaudiosrc; + GstElement *queue2; + GstElement *avsysaudiosink; + GstBuffer *output_buffer; +} mm_radio_gstreamer_s; +#endif + +typedef struct _mm_radio_event_s { + MMRadioEvent event_type; + int event_data; +} _mm_radio_event_s; + +typedef struct _mm_radio_tuning_s { + /* to check default or temp value*/ + int enable; + + int cnt_th; + int rssi_th; + int snr_th; + + /*soft mute*/ + int start_snr; + int stop_snr; + int start_rssi; + int stop_rssi; + int start_mute; + int stop_atten; + int mute_rate; + int snr40; + + /*recording volume*/ + int recording_volume_lower_thres; + int recording_volume_heigher_thres; + + /* sprd */ + int freq_offset; + int noise_power; + int pilot_power; + int softmute_enable; + +} mm_radio_tuning_t; + +typedef struct { + /* radio state */ + int current_state; + int old_state; + int pending_state; + + /*commad to be performed*/ + int cmd; + + /* command lock */ + pthread_mutex_t cmd_lock; + + /* volume set lock */ + pthread_mutex_t volume_lock; + + + /* radio attributes */ + MMHandleType *attrs; + + /* message callback */ + MMMessageCallback msg_cb; + void *msg_cb_param; + + /* radio device fd */ + int radio_fd; + + /* scan */ + pthread_t scan_thread; + int stop_scan; + + /* seek */ + pthread_t seek_thread; + MMRadioSeekDirectionType seek_direction; + int prev_seek_freq; + /*These parameters are inserted for better seek handling*/ + int is_seeking; + int seek_unmute; + bool seek_cancel; + + /* ASM */ + MMRadioASM sm; + + /*frequency*/ + int freq; + + /*mute*/ + int is_muted; + + /*Handle to vender specific attributes*/ + MMRadioVenderHandle vender_specific_handle; + + /*radio tuning structure*/ + mm_radio_tuning_t radio_tuning; + + /*to keep state changes atomic*/ + pthread_mutex_t state_mutex; +#ifdef USE_GST_PIPELINE + mm_radio_gstreamer_s *pGstreamer_s; +#endif + + /* region settings */ + MMRadioRegion_t region_setting; + + /*frequency changes*/ + pthread_t event_thread; + GAsyncQueue *event_queue; +} 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); +void _mmradio_seek_cancel(mm_radio_t *radio); +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, uint *min_freq, uint *max_freq); +#if 0 /* compile */ +int _mm_radio_enable_rds(mm_radio_t *radio); +int _mm_radio_disable_rds(mm_radio_t *radio); +int _mm_radio_is_rds_enabled(mm_radio_t *radio, bool *rds_enbled); + +int _mm_radio_enable_af(mm_radio_t *radio); +int _mm_radio_disable_af(mm_radio_t *radio); +int _mm_radio_is_af_enabled(mm_radio_t *radio, bool *rds_enbled); +#endif +int _mmradio_prepare_device(mm_radio_t *radio); +void _mmradio_unprepare_device(mm_radio_t *radio); + +#ifdef USE_GST_PIPELINE +int _mmradio_realize_pipeline(mm_radio_t *radio); +int _mmradio_start_pipeline(mm_radio_t *radio); +int _mmradio_stop_pipeline(mm_radio_t *radio); +int _mmradio_destroy_pipeline(mm_radio_t *radio); +#endif + +int _mm_radio_load_volume_table(int **volume_table, int *number_of_elements); +void _mm_radio_write_tuning_parameter(char *tuning_parameter, int tuning_value); +int _mm_create_temp_tuning_file(void); + +#if 0 +int mmradio_set_attrs(mm_radio_t *radio, MMRadioAttrsType type, MMHandleType attrs); +MMHandleType mmradio_get_attrs(mm_radio_t *radio, MMRadioAttrsType type); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __MM_Radio_INTERNAL_COMMON_H__ */ diff --git a/src/include/mm_radio_priv_v4l2.h b/src/include/mm_radio_priv_v4l2.h new file mode 100755 index 0000000..5b9877f --- /dev/null +++ b/src/include/mm_radio_priv_v4l2.h @@ -0,0 +1,136 @@ +/* + * libmm-radio + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: JongHyuk Choi , YoungHwan An + * + * 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_V4L2_H__ +#define __MM_Radio_INTERNAL_V4L2_H__ + +/*=========================================================================================== + INCLUDE FILES +========================================================================================== */ + +#include +#include +#include +#include +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*=========================================================================================== + GLOBAL DEFINITIONS AND DECLARATIONS FOR MODULE +========================================================================================== */ + +/*--------------------------------------------------------------------------- + GLOBAL #defines: +---------------------------------------------------------------------------*/ +#define MM_RADIO_NAME "radio" + +#define SAMPLEDELAY 15000 + +#if 0 /* 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" +#endif + +/* COMMON */ + +#define FMRX_DEVICE_STATUS "/sys/devices/virtual/video4linux/radio0/fmrx_status" +#define FMRX_RSSI_LEVEL_THRESHOLD "/sys/devices/virtual/video4linux/radio0/fmrx_rssi_lvl" + +/* for BRCM */ +#define FMRX_CURR_SNR "/sys/devices/virtual/video4linux/radio0/fmrx_curr_snr" +#define FMRX_CNT_THRESHOLD "/sys/devices/virtual/video4linux/radio0/fmrx_cos_th" +#define FMRX_SNR_LEVEL_THRESHOLD "/sys/devices/virtual/video4linux/radio0/fmrx_snr_lvl" + +/* for BRCM softmute*/ +#define FMRX_SOFT_MUTE_START_SNR "/sys/devices/virtual/video4linux/radio0/fmrx_start_snr" +#define FMRX_SOFT_MUTE_STOP_SNR "/sys/devices/virtual/video4linux/radio0/fmrx_stop_snr" +#define FMRX_SOFT_MUTE_START_RSSI "/sys/devices/virtual/video4linux/radio0/fmrx_start_rssi" +#define FMRX_SOFT_MUTE_STOP_RSSI "/sys/devices/virtual/video4linux/radio0/fmrx_stop_rssi" +#define FMRX_SOFT_MUTE_START_MUTE "/sys/devices/virtual/video4linux/radio0/fmrx_start_mute" +#define FMRX_SOFT_MUTE_STOP_ATTEN "/sys/devices/virtual/video4linux/radio0/fmrx_stop_atten" +#define FMRX_SOFT_MUTE_MUTE_RATE "/sys/devices/virtual/video4linux/radio0/fmrx_mute_rate" +#define FMRX_SOFT_MUTE_SNR_40 "/sys/devices/virtual/video4linux/radio0/fmrx_snr40" +#define FMRX_SOFT_MUTE_UPDATE "/sys/devices/virtual/video4linux/radio0/fmrx_set_blndmute" +#define FMRX_PROPERTY_SEARCH_ABORT "/sys/devices/virtual/video4linux/radio0/fmrx_search_abort" + +/* for SPRD */ +#define FMRX_TUNING_FREQ_OFFSET "/sys/class/video4linux/radio0/fmrx_freq_offset" +#define FMRX_TUNING_NOISE_POWER "/sys/class/video4linux/radio0/fmrx_noise_power" +#define FMRX_TUNING_PILOT_POWER "/sys/class/video4linux/radio0/fmrx_pilot_power" +#define FMRX_TUNING_ENABLE_DISABLE_SOFTMUTE "/sys/class/video4linux/radio0/fmrx_start_mute" + +#define DEV_OPEN_RETRY_COUNT 3 + +typedef struct { + pthread_t fade_volume_thread; + int initial_volume; + int final_volume; + int time_in_ms; + int number_of_steps; + int fade_finished; +} mm_radio_volume_fade_args; + +typedef struct { + /* device control */ + struct v4l2_capability vc; + struct v4l2_tuner vt; + struct v4l2_control vctrl; + struct v4l2_frequency vf; + + /* hw debug */ + struct v4l2_dbg_register reg; + + /*chipset specific flags*/ + int prev_seek_freq; + + /*seeek cancel atomic*/ + pthread_mutex_t seek_cancel_mutex; + + int device_ready; + + /*fadeup volume*/ + mm_radio_volume_fade_args volume_fade; +} mm_radio_priv_v4l2_t; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/include/mm_radio_utils.h b/src/include/mm_radio_utils.h index b873483..1f36d78 100644 --- a/src/include/mm_radio_utils.h +++ b/src/include/mm_radio_utils.h @@ -18,7 +18,7 @@ * limitations under the License. * */ - + #ifndef __MM_RADIO_UTILS_H__ #define __MM_RADIO_UTILS_H__ @@ -26,11 +26,14 @@ #include #include #include +#include /* radio log */ #define MMRADIO_LOG_FENTER debug_fenter #define MMRADIO_LOG_FLEAVE debug_fleave -#define MMRADIO_LOG_DEBUG debug_log +#define MMRADIO_LOG_INFO debug_msg +#define MMRADIO_LOG_DEBUG debug_msg +#define MMRADIO_LOG_VERBOSE debug_log #define MMRADIO_LOG_ERROR debug_error #define MMRADIO_LOG_WARNING debug_warning #define MMRADIO_LOG_CRITICAL debug_critical @@ -99,9 +102,26 @@ switch ( __mmradio_check_state(x_radio, x_command) ) \ break; \ } +#define MMRADIO_CHECK_STATE_GOTO_IF_FAIL(ret, x_radio, x_command, goto_label ) \ +debug_log("checking radio state before doing %s\n", #x_command); \ +switch ( __mmradio_check_state(x_radio, x_command) ) \ +{ \ + case MM_ERROR_RADIO_INVALID_STATE: \ + ret = MM_ERROR_RADIO_INVALID_STATE; \ + goto goto_label; \ + break; \ + /* NOTE : for robustness of mmfw. we won't treat it as an error */ \ + case MM_ERROR_RADIO_NO_OP: \ + ret = MM_ERROR_NONE; \ + goto goto_label; \ + break; \ + default: \ + break; \ +} + #define MMRADIO_CHECK_RETURN_IF_FAIL( x_ret, x_msg ) \ do \ -{ \ + { \ if( x_ret < 0 ) \ { \ debug_error("%s error\n", x_msg);\ @@ -109,5 +129,30 @@ do \ } \ } while( 0 ) ; -#endif +#define MMRADIO_CHECK_GOTO_IF_FAIL( x_ret, x_msg, goto_palce ) \ +do \ + { \ + if( x_ret < 0 ) \ + { \ + debug_error("%s error\n", x_msg);\ + goto goto_palce; \ + } \ +} while( 0 ) ; +typedef void *MMRadioVenderHandle; + +#define FM_RADIO_TUNING_DATA_INI_DUMP(dict, path) \ +do { \ + FILE *fp; \ + fp = fopen(path, "w"); \ + if (!fp) { \ + MMRADIO_LOG_WARNING("%s open failed", path); \ + } else { \ + iniparser_dump_ini(dict, fp); \ + fclose(fp); \ + } \ +} while(0) + +int event_comparator(gconstpointer a, gconstpointer b, gpointer user_data); + +#endif diff --git a/src/mm_radio.c b/src/mm_radio.c index ac93895..375c68d 100644 --- a/src/mm_radio.c +++ b/src/mm_radio.c @@ -32,6 +32,7 @@ #include #include #include "mm_debug.h" +#include "ttrace.h" /*=========================================================================================== | | @@ -84,39 +85,37 @@ int mm_radio_create(MMHandleType *hradio) { int result = MM_ERROR_NONE; - mm_radio_t* new_radio = NULL; - + mm_radio_t *new_radio = NULL; + TTRACE_BEGIN("MMRADIO:CREATE"); MMRADIO_LOG_FENTER(); return_val_if_fail(hradio, MM_ERROR_RADIO_NOT_INITIALIZED); /* alloc radio structure */ - new_radio = (mm_radio_t*) malloc(sizeof(mm_radio_t)); - if ( ! new_radio ) - { + new_radio = (mm_radio_t *) malloc(sizeof(mm_radio_t)); + if (!new_radio) { debug_critical("cannot allocate memory for radio\n"); goto ERROR; } memset(new_radio, 0, sizeof(mm_radio_t)); /* internal creation stuffs */ - result = _mmradio_create_radio( new_radio ); + result = _mmradio_create_radio(new_radio); - if(result != MM_ERROR_NONE) + if (result != MM_ERROR_NONE) goto ERROR; *hradio = (MMHandleType)new_radio; - + TTRACE_END(); MMRADIO_LOG_FLEAVE(); return result; ERROR: - if ( new_radio ) - { - MMRADIO_FREEIF( new_radio ); + if (new_radio) { + MMRADIO_FREEIF(new_radio); } *hradio = (MMHandleType)0; @@ -130,24 +129,23 @@ ERROR: int mm_radio_destroy(MMHandleType hradio) { int result = MM_ERROR_NONE; - mm_radio_t* radio = (mm_radio_t*)hradio; - + mm_radio_t *radio = (mm_radio_t *)hradio; + TTRACE_BEGIN("MMRADIO:DESTROY"); MMRADIO_LOG_FENTER(); return_val_if_fail(radio, MM_ERROR_RADIO_NOT_INITIALIZED); - result = _mmradio_destroy( radio ); + result = _mmradio_destroy(radio); - if ( result != MM_ERROR_NONE ) - { + if (result != MM_ERROR_NONE) { debug_error("failed to destroy radio\n"); } /* free radio */ - MMRADIO_FREEIF( radio ); - + MMRADIO_FREEIF(radio); + TTRACE_END(); MMRADIO_LOG_FLEAVE(); return result; @@ -156,17 +154,17 @@ int mm_radio_destroy(MMHandleType hradio) int mm_radio_realize(MMHandleType hradio) { int result = MM_ERROR_NONE; - mm_radio_t* radio = (mm_radio_t*)hradio; + mm_radio_t *radio = (mm_radio_t *)hradio; MMRADIO_LOG_FENTER(); return_val_if_fail(radio, MM_ERROR_RADIO_NOT_INITIALIZED); - MMRADIO_CMD_LOCK( radio ); + MMRADIO_CMD_LOCK(radio); - result = _mmradio_realize( radio ); + result = _mmradio_realize(radio); - MMRADIO_CMD_UNLOCK( radio ); + MMRADIO_CMD_UNLOCK(radio); MMRADIO_LOG_FLEAVE(); @@ -176,17 +174,25 @@ int mm_radio_realize(MMHandleType hradio) int mm_radio_unrealize(MMHandleType hradio) { int result = MM_ERROR_NONE; - mm_radio_t* radio = (mm_radio_t*)hradio; + mm_radio_t *radio = (mm_radio_t *)hradio; + MMRadioStateType state = 0; MMRADIO_LOG_FENTER(); return_val_if_fail(radio, MM_ERROR_RADIO_NOT_INITIALIZED); - MMRADIO_CMD_LOCK( radio ); + mm_radio_get_state((hradio), &state); + MMRADIO_SLOG_DEBUG("mm_radio_unrealize state: %d\n", state); - result = _mmradio_unrealize( radio ); + if (state == MM_RADIO_STATE_SCANNING) { + mm_radio_scan_stop(hradio); + } - MMRADIO_CMD_UNLOCK( radio ); + MMRADIO_CMD_LOCK(radio); + + result = _mmradio_unrealize(radio); + + MMRADIO_CMD_UNLOCK(radio); MMRADIO_LOG_FLEAVE(); @@ -196,27 +202,27 @@ int mm_radio_unrealize(MMHandleType hradio) int mm_radio_set_message_callback(MMHandleType hradio, MMMessageCallback callback, void *user_param) { int result = MM_ERROR_NONE; - mm_radio_t* radio = (mm_radio_t*)hradio; + mm_radio_t *radio = (mm_radio_t *)hradio; MMRADIO_LOG_FENTER(); return_val_if_fail(radio, MM_ERROR_RADIO_NOT_INITIALIZED); - MMRADIO_CMD_LOCK( radio ); + MMRADIO_CMD_LOCK(radio); - result = _mmradio_set_message_callback( radio, callback, user_param ); + result = _mmradio_set_message_callback(radio, callback, user_param); - MMRADIO_CMD_UNLOCK( radio ); + MMRADIO_CMD_UNLOCK(radio); MMRADIO_LOG_FLEAVE(); return result; } -int mm_radio_get_state(MMHandleType hradio, MMRadioStateType* pState) +int mm_radio_get_state(MMHandleType hradio, MMRadioStateType *pState) { int result = MM_ERROR_NONE; - mm_radio_t* radio = (mm_radio_t*)hradio; + mm_radio_t *radio = (mm_radio_t *)hradio; int state = 0; MMRADIO_LOG_FENTER(); @@ -224,13 +230,13 @@ int mm_radio_get_state(MMHandleType hradio, MMRadioStateType* pState) return_val_if_fail(radio, MM_ERROR_RADIO_NOT_INITIALIZED); return_val_if_fail(pState, MM_ERROR_COMMON_INVALID_ARGUMENT); - MMRADIO_CMD_LOCK( radio ); + MMRADIO_CMD_LOCK(radio); - result = _mmradio_get_state( radio, &state ); + result = _mmradio_get_state(radio, &state); *pState = state; - MMRADIO_CMD_UNLOCK( radio ); + MMRADIO_CMD_UNLOCK(radio); MMRADIO_LOG_FLEAVE(); @@ -240,18 +246,18 @@ int mm_radio_get_state(MMHandleType hradio, MMRadioStateType* pState) int mm_radio_start(MMHandleType hradio) { int result = MM_ERROR_NONE; - mm_radio_t* radio = (mm_radio_t*)hradio; - + mm_radio_t *radio = (mm_radio_t *)hradio; + TTRACE_BEGIN("MMRADIO:START"); MMRADIO_LOG_FENTER(); return_val_if_fail(radio, MM_ERROR_RADIO_NOT_INITIALIZED); - MMRADIO_CMD_LOCK( radio ); - - result = _mmradio_start( radio ); + MMRADIO_CMD_LOCK(radio); - MMRADIO_CMD_UNLOCK( radio ); + result = _mmradio_start(radio); + MMRADIO_CMD_UNLOCK(radio); + TTRACE_END(); MMRADIO_LOG_FLEAVE(); return result; @@ -260,17 +266,17 @@ int mm_radio_start(MMHandleType hradio) int mm_radio_stop(MMHandleType hradio) { int result = MM_ERROR_NONE; - mm_radio_t* radio = (mm_radio_t*)hradio; + mm_radio_t *radio = (mm_radio_t *)hradio; MMRADIO_LOG_FENTER(); return_val_if_fail(radio, MM_ERROR_RADIO_NOT_INITIALIZED); - MMRADIO_CMD_LOCK( radio ); + MMRADIO_CMD_LOCK(radio); - result = _mmradio_stop( radio ); + result = _mmradio_stop(radio); - MMRADIO_CMD_UNLOCK( radio ); + MMRADIO_CMD_UNLOCK(radio); MMRADIO_LOG_FLEAVE(); @@ -280,20 +286,20 @@ int mm_radio_stop(MMHandleType hradio) int mm_radio_seek(MMHandleType hradio, MMRadioSeekDirectionType direction) { int result = MM_ERROR_NONE; - mm_radio_t* radio = (mm_radio_t*)hradio; + mm_radio_t *radio = (mm_radio_t *)hradio; MMRADIO_LOG_FENTER(); return_val_if_fail(radio, MM_ERROR_RADIO_NOT_INITIALIZED); return_val_if_fail(direction >= MM_RADIO_SEEK_UP && direction <= MM_RADIO_SEEK_DOWN, MM_ERROR_INVALID_ARGUMENT); - MMRADIO_CMD_LOCK( radio ); + MMRADIO_CMD_LOCK(radio); radio->seek_direction = direction; - result = _mmradio_seek( radio, direction ); + result = _mmradio_seek(radio, direction); - MMRADIO_CMD_UNLOCK( radio ); + MMRADIO_CMD_UNLOCK(radio); MMRADIO_LOG_FLEAVE(); @@ -303,27 +309,27 @@ int mm_radio_seek(MMHandleType hradio, MMRadioSeekDirectionType direction) int mm_radio_set_frequency(MMHandleType hradio, int freq) { int result = MM_ERROR_NONE; - mm_radio_t* radio = (mm_radio_t*)hradio; + mm_radio_t *radio = (mm_radio_t *)hradio; MMRADIO_LOG_FENTER(); return_val_if_fail(radio, MM_ERROR_RADIO_NOT_INITIALIZED); - MMRADIO_CMD_LOCK( radio ); + MMRADIO_CMD_LOCK(radio); - result = _mmradio_set_frequency( radio, freq ); + result = _mmradio_set_frequency(radio, freq); - MMRADIO_CMD_UNLOCK( radio ); + MMRADIO_CMD_UNLOCK(radio); MMRADIO_LOG_FLEAVE(); return result; } -int mm_radio_get_frequency(MMHandleType hradio, int* pFreq) +int mm_radio_get_frequency(MMHandleType hradio, int *pFreq) { int result = MM_ERROR_NONE; - mm_radio_t* radio = (mm_radio_t*)hradio; + mm_radio_t *radio = (mm_radio_t *)hradio; int freq = 0; MMRADIO_LOG_FENTER(); @@ -331,13 +337,13 @@ int mm_radio_get_frequency(MMHandleType hradio, int* pFreq) return_val_if_fail(radio, MM_ERROR_RADIO_NOT_INITIALIZED); return_val_if_fail(pFreq, MM_ERROR_INVALID_ARGUMENT); - MMRADIO_CMD_LOCK( radio ); + MMRADIO_CMD_LOCK(radio); - result = _mmradio_get_frequency( radio, &freq ); + result = _mmradio_get_frequency(radio, &freq); *pFreq = freq; - MMRADIO_CMD_UNLOCK( radio ); + MMRADIO_CMD_UNLOCK(radio); MMRADIO_LOG_FLEAVE(); @@ -347,17 +353,17 @@ int mm_radio_get_frequency(MMHandleType hradio, int* pFreq) int mm_radio_scan_start(MMHandleType hradio) { int result = MM_ERROR_NONE; - mm_radio_t* radio = (mm_radio_t*)hradio; + mm_radio_t *radio = (mm_radio_t *)hradio; MMRADIO_LOG_FENTER(); return_val_if_fail(radio, MM_ERROR_RADIO_NOT_INITIALIZED); - MMRADIO_CMD_LOCK( radio ); + MMRADIO_CMD_LOCK(radio); - result = _mmradio_start_scan( radio ); + result = _mmradio_start_scan(radio); - MMRADIO_CMD_UNLOCK( radio ); + MMRADIO_CMD_UNLOCK(radio); MMRADIO_LOG_FLEAVE(); @@ -367,17 +373,17 @@ int mm_radio_scan_start(MMHandleType hradio) int mm_radio_scan_stop(MMHandleType hradio) { int result = MM_ERROR_NONE; - mm_radio_t* radio = (mm_radio_t*)hradio; + mm_radio_t *radio = (mm_radio_t *)hradio; MMRADIO_LOG_FENTER(); return_val_if_fail(radio, MM_ERROR_RADIO_NOT_INITIALIZED); - MMRADIO_CMD_LOCK( radio ); + MMRADIO_CMD_LOCK(radio); - result = _mmradio_stop_scan( radio ); + result = _mmradio_stop_scan(radio); - MMRADIO_CMD_UNLOCK( radio ); + MMRADIO_CMD_UNLOCK(radio); MMRADIO_LOG_FLEAVE(); @@ -387,7 +393,7 @@ int mm_radio_scan_stop(MMHandleType hradio) int mm_radio_set_mute(MMHandleType hradio, bool muted) { int result = MM_ERROR_NONE; - mm_radio_t* radio = (mm_radio_t*)hradio; + mm_radio_t *radio = (mm_radio_t *)hradio; MMRADIO_LOG_FENTER(); @@ -395,12 +401,9 @@ int mm_radio_set_mute(MMHandleType hradio, bool muted) MMRADIO_CMD_LOCK(radio); - if (muted) - { + if (muted) { result = _mmradio_mute(radio); - } - else - { + } else { result = _mmradio_unmute(radio); } @@ -420,13 +423,13 @@ int mm_radio_get_signal_strength(MMHandleType hradio, int *value) int ret = MM_ERROR_NONE; - mm_radio_t* radio = (mm_radio_t*)hradio; + mm_radio_t *radio = (mm_radio_t *)hradio; - MMRADIO_CMD_LOCK( radio ); + MMRADIO_CMD_LOCK(radio); ret = _mm_radio_get_signal_strength(radio, value); - MMRADIO_CMD_UNLOCK( radio ); + MMRADIO_CMD_UNLOCK(radio); MMRADIO_LOG_DEBUG("signal strength = %d\n", *value); MMRADIO_LOG_FLEAVE(); @@ -441,7 +444,7 @@ int mm_radio_get_region_type(MMHandleType hradio, MMRadioRegionType *type) return_val_if_fail(type, MM_ERROR_INVALID_ARGUMENT); int result = MM_ERROR_NONE; - mm_radio_t* radio = (mm_radio_t*)hradio; + mm_radio_t *radio = (mm_radio_t *)hradio; MMRadioRegionType cur_type = MM_RADIO_REGION_GROUP_NONE; result = _mmradio_get_region_type(radio, &cur_type); @@ -453,7 +456,7 @@ int mm_radio_get_region_type(MMHandleType hradio, MMRadioRegionType *type) return result; } -int mm_radio_get_region_frequency_range(MMHandleType hradio, unsigned int *min, unsigned int*max) +int mm_radio_get_region_frequency_range(MMHandleType hradio, unsigned int *min, unsigned int *max) { MMRADIO_LOG_FENTER(); @@ -461,14 +464,13 @@ int mm_radio_get_region_frequency_range(MMHandleType hradio, unsigned int *min, return_val_if_fail(min && max, MM_ERROR_INVALID_ARGUMENT); int result = MM_ERROR_NONE; - mm_radio_t* radio = (mm_radio_t*)hradio; + mm_radio_t *radio = (mm_radio_t *)hradio; unsigned int min_freq = 0; unsigned int max_freq = 0; result = _mmradio_get_region_frequency_range(radio, &min_freq, &max_freq); - if (result == MM_ERROR_NONE) - { + if (result == MM_ERROR_NONE) { *min = min_freq; *max = max_freq; } @@ -477,3 +479,25 @@ int mm_radio_get_region_frequency_range(MMHandleType hradio, unsigned int *min, return result; } +int mm_radio_get_channel_spacing(MMHandleType hradio, int *channel_spacing) +{ + MMRADIO_LOG_FENTER(); + + return_val_if_fail(hradio, MM_ERROR_RADIO_NOT_INITIALIZED); + return_val_if_fail(channel_spacing, MM_ERROR_INVALID_ARGUMENT); + + int result = MM_ERROR_NONE; + mm_radio_t *radio = (mm_radio_t *)hradio; + unsigned int ch_spacing = 0; + + result = _mmradio_get_channel_spacing(radio, &ch_spacing); + + if (result == MM_ERROR_NONE) { + *channel_spacing = ch_spacing; + } + + MMRADIO_LOG_FLEAVE(); + return result; +} + + diff --git a/src/mm_radio_asm.c b/src/mm_radio_asm.c index 9dacda1..32ef6bc 100644 --- a/src/mm_radio_asm.c +++ b/src/mm_radio_asm.c @@ -24,7 +24,7 @@ #include "mm_radio_asm.h" #include "mm_radio_utils.h" -int mmradio_asm_register(MMRadioASM* sm, ASM_sound_cb_t callback, void* param) +int mmradio_asm_register(MMRadioASM *sm, ASM_sound_cb_t callback, void *param) { /* read mm-session information */ int session_type = MM_SESSION_TYPE_MEDIA; @@ -36,49 +36,40 @@ int mmradio_asm_register(MMRadioASM* sm, ASM_sound_cb_t callback, void* param) MMRADIO_LOG_FENTER(); - if ( ! sm ) - { + if (!sm) { MMRADIO_LOG_ERROR("invalid session handle\n"); return MM_ERROR_RADIO_NOT_INITIALIZED; } /* read session information */ errorcode = _mm_session_util_read_information(pid, &session_type, &session_options); - if ( errorcode ) - { + if (errorcode) { debug_warning("Read Session Information failed. use default \"media\" type\n"); session_type = MM_SESSION_TYPE_MEDIA; } /* check if it's MEDIA type */ - if ( session_type != MM_SESSION_TYPE_MEDIA) - { + 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 */ - if ( sm->pid > 0 ) - { + if (sm->pid > 0) { pid = sm->pid; MMRADIO_LOG_DEBUG("mm-radio is running on different process. Just faking pid to [%d]. :-p\n", pid); - } - else - { + } else { MMRADIO_LOG_DEBUG("no pid has assigned. using default(current) context\n"); } /* register audio-session-manager callback */ - if( ! ASM_register_sound(pid, &asm_handle, event_type, ASM_STATE_NONE, callback, (void*)param, ASM_RESOURCE_NONE, &errorcode)) - { + if (!ASM_register_sound(pid, &asm_handle, event_type, ASM_STATE_NONE, callback, (void *)param, ASM_RESOURCE_NONE, &errorcode)) { MMRADIO_LOG_CRITICAL("ASM_register_sound() failed\n"); return errorcode; } /* set session options */ - if (session_options) - { - if( ! ASM_set_session_option(asm_handle, session_options, &errorcode)) - { + if (session_options) { + if (!ASM_set_session_option(asm_handle, session_options, &errorcode)) { debug_error("ASM_set_session_options() failed, error(%x)\n", errorcode); return errorcode; } @@ -93,21 +84,19 @@ int mmradio_asm_register(MMRadioASM* sm, ASM_sound_cb_t callback, void* param) return MM_ERROR_NONE; } -int mmradio_asm_deregister(MMRadioASM* sm) +int mmradio_asm_deregister(MMRadioASM *sm) { int event_type = ASM_EVENT_MEDIA_FMRADIO; int errorcode = 0; MMRADIO_LOG_FENTER(); - if ( ! sm ) - { + if (!sm) { MMRADIO_LOG_ERROR("invalid session handle\n"); return MM_ERROR_RADIO_NOT_INITIALIZED; } - if( ! ASM_unregister_sound( sm->handle, event_type, &errorcode) ) - { + if (!ASM_unregister_sound(sm->handle, event_type, &errorcode)) { MMRADIO_LOG_ERROR("Unregister sound failed 0x%X\n", errorcode); return MM_ERROR_POLICY_INTERNAL; } @@ -117,32 +106,27 @@ int mmradio_asm_deregister(MMRadioASM* sm) return MM_ERROR_NONE; } -int mmradio_asm_set_state(MMRadioASM* sm, ASM_sound_states_t state, ASM_resource_t resource) +int mmradio_asm_set_state(MMRadioASM *sm, ASM_sound_states_t state, ASM_resource_t resource) { int event_type = ASM_EVENT_MEDIA_FMRADIO; MMRADIO_LOG_FENTER(); - if ( ! sm ) - { + if (!sm) { MMRADIO_LOG_ERROR("invalid session handle\n"); return MM_ERROR_RADIO_NOT_INITIALIZED; } - if ( sm->by_asm_cb == MMRADIO_ASM_CB_NONE ) //|| sm->state == ASM_STATE_PLAYING ) - { + if (sm->by_asm_cb == MMRADIO_ASM_CB_NONE) { /*|| sm->state == ASM_STATE_PLAYING ) */ int ret = 0; - if( ! ASM_set_sound_state( sm->handle, event_type, state, resource, &ret) ) - { + if (!ASM_set_sound_state(sm->handle, event_type, state, resource, &ret)) { MMRADIO_LOG_ERROR("set ASM state to [%d] failed 0x%X\n", state, ret); return MM_ERROR_POLICY_BLOCKED; } sm->state = state; - } - else // by asm callback - { + } else { /* by asm callback */ sm->by_asm_cb = MMRADIO_ASM_CB_NONE; sm->state = state; } @@ -152,3 +136,4 @@ int mmradio_asm_set_state(MMRadioASM* sm, ASM_sound_states_t state, ASM_resource return MM_ERROR_NONE; } + diff --git a/src/mm_radio_priv.c b/src/mm_radio_priv.c index 8b00010..b3450b4 100644 --- a/src/mm_radio_priv.c +++ b/src/mm_radio_priv.c @@ -67,7 +67,7 @@ #define FREQ_FRAC 16 #define RADIO_FREQ_FORMAT_SET(x_freq) ((x_freq) * FREQ_FRAC) #define RADIO_FREQ_FORMAT_GET(x_freq) ((x_freq) / FREQ_FRAC) -#define DEFAULT_WRAP_AROUND 1 //If non-zero, wrap around when at the end of the frequency range, else stop seeking +#define DEFAULT_WRAP_AROUND 1 /*If non-zero, wrap around when at the end of the frequency range, else stop seeking */ #define RADIO_DEFAULT_REGION MM_RADIO_REGION_GROUP_USA #define READ_MAX_BUFFER_SIZE 1024 @@ -88,40 +88,47 @@ extern int errno; LOCAL VARIABLE DEFINITIONS: ---------------------------------------------------------------------------*/ /* radio region configuration table */ -static const MMRadioRegion_t region_table[] = -{ - { /* Notrh America, South America, South Korea, Taiwan, Australia */ - MM_RADIO_REGION_GROUP_USA, // region type - MM_RADIO_DEEMPHASIS_75_US, // de-emphasis - MM_RADIO_FREQ_MIN_87500_KHZ, // min freq. - MM_RADIO_FREQ_MAX_108000_KHZ, // max freq. - }, - { /* China, Europe, Africa, Middle East, Hong Kong, India, Indonesia, Russia, Singapore */ - MM_RADIO_REGION_GROUP_EUROPE, - MM_RADIO_DEEMPHASIS_50_US, - MM_RADIO_FREQ_MIN_87500_KHZ, - MM_RADIO_FREQ_MAX_108000_KHZ, - }, - { - MM_RADIO_REGION_GROUP_JAPAN, - MM_RADIO_DEEMPHASIS_50_US, - MM_RADIO_FREQ_MIN_76100_KHZ, - MM_RADIO_FREQ_MAX_89900_KHZ, - }, +static const MMRadioRegion_t region_table[] = { + { /* Notrh America, South America, South Korea, Taiwan, Australia */ + MM_RADIO_REGION_GROUP_USA, /* region type */ + MM_RADIO_DEEMPHASIS_75_US, /* de-emphasis */ + MM_RADIO_FREQ_MIN_87500_KHZ, /* min freq. */ + MM_RADIO_FREQ_MAX_108000_KHZ, /* max freq. */ + 50, + }, + { /* China, Europe, Africa, Middle East, Hong Kong, India, Indonesia, Russia, Singapore */ + MM_RADIO_REGION_GROUP_EUROPE, + MM_RADIO_DEEMPHASIS_50_US, + MM_RADIO_FREQ_MIN_87500_KHZ, + MM_RADIO_FREQ_MAX_108000_KHZ, + 50, + }, + { + MM_RADIO_REGION_GROUP_JAPAN, + MM_RADIO_DEEMPHASIS_50_US, + MM_RADIO_FREQ_MIN_76100_KHZ, + MM_RADIO_FREQ_MAX_89900_KHZ, + 50, + }, }; /*--------------------------------------------------------------------------- LOCAL FUNCTION PROTOTYPES: ---------------------------------------------------------------------------*/ -static bool __mmradio_post_message(mm_radio_t* radio, enum MMMessageType msgtype, MMMessageParamType* param); -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); -static void __mmradio_seek_thread(mm_radio_t* radio); -static void __mmradio_scan_thread(mm_radio_t* radio); -ASM_cb_result_t __mmradio_asm_callback(int handle, ASM_event_sources_t sound_event, ASM_sound_commands_t command, unsigned int sound_status, void* cb_data); -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 bool __mmradio_post_message(mm_radio_t *radio, enum MMMessageType msgtype, MMMessageParamType *param); +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); +static void __mmradio_seek_thread(mm_radio_t *radio); +static void __mmradio_scan_thread(mm_radio_t *radio); +#ifdef FEATURE_ASM_SUPPORT +ASM_cb_result_t __mmradio_asm_callback(int handle, ASM_event_sources_t sound_event, ASM_sound_commands_t command, unsigned int sound_status, void *cb_data); +#else +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, const char *additional_info, void *user_data); +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 +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); /*=========================================================================== FUNCTION DEFINITIONS @@ -136,7 +143,7 @@ static int __mmradio_set_band_range(mm_radio_t* radio); * Return : zero on success, or negative value with error code *---------------------------------------------------------------------------*/ int -_mmradio_apply_region(mm_radio_t* radio, MMRadioRegionType region, bool update) +_mmradio_apply_region(mm_radio_t *radio, MMRadioRegionType region, bool update) { int ret = MM_ERROR_NONE; int count = 0; @@ -144,41 +151,38 @@ _mmradio_apply_region(mm_radio_t* radio, MMRadioRegionType region, bool update) MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); - MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_SET_REGION ); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_REGION); /* if needed, radio region must be updated. * Otherwise, just applying settings to device without it. */ - if ( update ) - { + if (update) { count = ARRAY_SIZE(region_table); - //TODO: if auto is supported...get the region info. here + /*TODO: if auto is supported...get the region info. here */ /* update radio region settings */ - for ( index = 0; index < count; index++ ) - { + for (index = 0; index < count; index++) { /* find the region from pre-defined table*/ - if (region_table[index].country == region) - { + if (region_table[index].country == region) { radio->region_setting.country = region_table[index].country; radio->region_setting.deemphasis = region_table[index].deemphasis; radio->region_setting.band_min = region_table[index].band_min; radio->region_setting.band_max = region_table[index].band_max; + radio->region_setting.channel_spacing = region_table[index].channel_spacing; } } } /* chech device is opened or not. if it's not ready, skip to apply region to device now*/ - if (radio->radio_fd < 0) - { + if (radio->radio_fd < 0) { MMRADIO_LOG_DEBUG("not opened device. just updating region info. \n"); return MM_ERROR_NONE; } MMRADIO_SLOG_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); + 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); @@ -196,14 +200,14 @@ _mmradio_apply_region(mm_radio_t* radio, MMRadioRegionType region, bool update) } int -_mmradio_create_radio(mm_radio_t* radio) +_mmradio_create_radio(mm_radio_t *radio) { int ret = 0; MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); - MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_CREATE ); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_CREATE); /* set default value */ radio->radio_fd = -1; @@ -211,19 +215,21 @@ _mmradio_create_radio(mm_radio_t* radio) memset(&radio->region_setting, 0, sizeof(MMRadioRegion_t)); /* create command lock */ - ret = pthread_mutex_init( &radio->cmd_lock, NULL ); - if ( ret ) - { + ret = pthread_mutex_init(&radio->cmd_lock, NULL); + if (ret) { MMRADIO_LOG_ERROR("mutex creation failed\n"); return MM_ERROR_RADIO_INTERNAL; } - MMRADIO_SET_STATE( radio, MM_RADIO_STATE_NULL ); + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_NULL); /* register to ASM */ - ret = mmradio_asm_register(&radio->sm, __mmradio_asm_callback, (void*)radio); - if ( ret ) - { +#ifdef FEATURE_ASM_SUPPORT + ret = mmradio_asm_register(&radio->sm, __mmradio_asm_callback, (void *)radio); +#else + ret = mmradio_audio_focus_register(&radio->sm, _mmradio_sound_focus_cb, (void *)radio); +#endif + if (ret) { /* NOTE : we are dealing it as an error since we cannot expect it's behavior */ MMRADIO_LOG_ERROR("failed to register asm server\n"); return MM_ERROR_RADIO_INTERNAL; @@ -235,32 +241,29 @@ _mmradio_create_radio(mm_radio_t* radio) } int -_mmradio_realize(mm_radio_t* radio) +_mmradio_realize(mm_radio_t *radio) { int ret = MM_ERROR_NONE; char str_error[READ_MAX_BUFFER_SIZE]; MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); - MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_REALIZE ); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_REALIZE); /* open radio device */ - if(radio->radio_fd == -1) - { + 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) - { + 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); + DEFAULT_DEVICE, strerror_r(errno, str_error, sizeof(str_error)), errno); /* check error */ - switch (errno) - { + switch (errno) { case ENOENT: return MM_ERROR_RADIO_DEVICE_NOT_FOUND; case EACCES: @@ -272,14 +275,12 @@ _mmradio_realize(mm_radio_t* radio) 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) - { + 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) ) - { + if (!(radio->vc.capabilities & V4L2_CAP_TUNER)) { MMRADIO_LOG_ERROR("this system can't support fm-radio!\n"); goto error; } @@ -287,13 +288,10 @@ _mmradio_realize(mm_radio_t* radio) /* set tuner audio mode */ ioctl(radio->radio_fd, VIDIOC_G_TUNER, &(radio->vt)); - if ( ! ( (radio->vt).capability & V4L2_TUNER_CAP_STEREO) ) - { + 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 - { + } else { (radio->vt).audmode = V4L2_TUNER_MODE_STEREO; } @@ -302,14 +300,11 @@ _mmradio_realize(mm_radio_t* radio) 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) - { + 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 - { + } else { /* already initialized by application */ region = radio->region_setting.country; } @@ -319,13 +314,13 @@ _mmradio_realize(mm_radio_t* radio) } /* ready but nosound */ - if( _mmradio_mute(radio) != MM_ERROR_NONE) + if (_mmradio_mute(radio) != MM_ERROR_NONE) goto error; - MMRADIO_SET_STATE( radio, MM_RADIO_STATE_READY ); + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY); #ifdef USE_GST_PIPELINE ret = _mmradio_realize_pipeline(radio); - if ( ret ) { + if (ret) { debug_error("_mmradio_realize_pipeline is failed\n"); return ret; } @@ -335,8 +330,7 @@ _mmradio_realize(mm_radio_t* radio) return MM_ERROR_NONE; error: - if (radio->radio_fd >= 0) - { + if (radio->radio_fd >= 0) { close(radio->radio_fd); radio->radio_fd = -1; } @@ -347,29 +341,31 @@ error: } int -_mmradio_unrealize(mm_radio_t* radio) +_mmradio_unrealize(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_UNREALIZE ); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_UNREALIZE); - if( _mmradio_mute(radio) != MM_ERROR_NONE) + if (_mmradio_mute(radio) != MM_ERROR_NONE) return MM_ERROR_RADIO_NOT_INITIALIZED; /* close radio device here !!!! */ - if (radio->radio_fd >= 0) - { + if (radio->radio_fd >= 0) { close(radio->radio_fd); radio->radio_fd = -1; } - MMRADIO_SET_STATE( radio, MM_RADIO_STATE_NULL ); + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_NULL); +#ifndef FEATURE_ASM_SUPPORT + ret = mmradio_set_audio_focus(&radio->sm, _mmradio_sound_focus_watch_cb, FALSE, (void *)radio); +#endif #ifdef USE_GST_PIPELINE - ret= _mmradio_destroy_pipeline(radio); - if ( ret ) { + ret = _mmradio_destroy_pipeline(radio); + if (ret) { debug_error("_mmradio_destroy_pipeline is failed\n"); return ret; } @@ -381,22 +377,25 @@ _mmradio_unrealize(mm_radio_t* radio) } int -_mmradio_destroy(mm_radio_t* radio) +_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 ); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_DESTROY); +#ifdef FEATURE_ASM_SUPPORT ret = mmradio_asm_deregister(&radio->sm); - if ( ret ) - { +#else + ret = mmradio_audio_focus_deregister(&radio->sm); +#endif + if (ret) { MMRADIO_LOG_ERROR("failed to deregister asm server\n"); return MM_ERROR_RADIO_INTERNAL; } - _mmradio_unrealize( radio ); + _mmradio_unrealize(radio); MMRADIO_LOG_FLEAVE(); @@ -405,27 +404,25 @@ _mmradio_destroy(mm_radio_t* radio) int -_mmradio_set_frequency(mm_radio_t* radio, int freq) // unit should be KHz +_mmradio_set_frequency(mm_radio_t *radio, int freq) /* unit should be KHz */ { MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); - MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_SET_FREQ ); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_FREQ); MMRADIO_SLOG_DEBUG("Setting %d frequency\n", freq); radio->freq = freq; - if (radio->radio_fd < 0) - { + 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 ) - { + 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; } @@ -434,8 +431,7 @@ _mmradio_set_frequency(mm_radio_t* radio, int freq) // unit should be KHz (radio->vf).tuner = 0; (radio->vf).frequency = RADIO_FREQ_FORMAT_SET(freq); - if(ioctl(radio->radio_fd, VIDIOC_S_FREQUENCY, &(radio->vf))< 0) - { + if (ioctl(radio->radio_fd, VIDIOC_S_FREQUENCY, &(radio->vf)) < 0) { return MM_ERROR_RADIO_NOT_INITIALIZED; } @@ -446,26 +442,24 @@ _mmradio_set_frequency(mm_radio_t* radio, int freq) // unit should be KHz } int -_mmradio_get_frequency(mm_radio_t* radio, int* pFreq) +_mmradio_get_frequency(mm_radio_t *radio, int *pFreq) { int freq = 0; MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); - MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_GET_FREQ ); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_FREQ); - return_val_if_fail( pFreq, MM_ERROR_INVALID_ARGUMENT ); + return_val_if_fail(pFreq, MM_ERROR_INVALID_ARGUMENT); /* just return stored frequency if radio device is not ready */ - if ( radio->radio_fd < 0 ) - { + if (radio->radio_fd < 0) { MMRADIO_SLOG_DEBUG("freq : %d\n", radio->freq); *pFreq = radio->freq; return MM_ERROR_NONE; } - if (ioctl(radio->radio_fd, VIDIOC_G_FREQUENCY, &(radio->vf)) < 0) - { + 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; } @@ -483,23 +477,21 @@ _mmradio_get_frequency(mm_radio_t* radio, int* pFreq) } int -_mmradio_mute(mm_radio_t* radio) +_mmradio_mute(mm_radio_t *radio) { MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); - MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_MUTE ); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_MUTE); - if (radio->radio_fd < 0) - { + if (radio->radio_fd < 0) { return MM_ERROR_RADIO_NOT_INITIALIZED; } (radio->vctrl).id = V4L2_CID_AUDIO_MUTE; - (radio->vctrl).value = 1; //mute + (radio->vctrl).value = 1; /*mute */ - if (ioctl(radio->radio_fd, VIDIOC_S_CTRL, &(radio->vctrl)) < 0) - { + if (ioctl(radio->radio_fd, VIDIOC_S_CTRL, &(radio->vctrl)) < 0) { return MM_ERROR_RADIO_NOT_INITIALIZED; } @@ -510,19 +502,18 @@ _mmradio_mute(mm_radio_t* radio) } int -_mmradio_unmute(mm_radio_t* radio) +_mmradio_unmute(mm_radio_t *radio) { MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); - MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_UNMUTE ); - MMRADIO_CHECK_DEVICE_STATE( radio ); + 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; - (radio->vctrl).value = 0; //unmute + (radio->vctrl).value = 0; /*unmute */ - if (ioctl(radio->radio_fd, VIDIOC_S_CTRL, &(radio->vctrl)) < 0) - { + if (ioctl(radio->radio_fd, VIDIOC_S_CTRL, &(radio->vctrl)) < 0) { return MM_ERROR_RADIO_NOT_INITIALIZED; } @@ -539,23 +530,22 @@ _mmradio_unmute(mm_radio_t* radio) * Return : zero on success, or negative value with error code *---------------------------------------------------------------------------*/ int -__mmradio_set_deemphasis(mm_radio_t* radio) +__mmradio_set_deemphasis(mm_radio_t *radio) { int value = 0; MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); + MMRADIO_CHECK_INSTANCE(radio); /* get de-emphasis */ - switch (radio->region_setting.deemphasis) - { + switch (radio->region_setting.deemphasis) { case MM_RADIO_DEEMPHASIS_50_US: - value = 1;//V4L2_DEEMPHASIS_50_uS; + value = 1;/*V4L2_DEEMPHASIS_50_uS; */ break; case MM_RADIO_DEEMPHASIS_75_US: - value = 2;//V4L2_DEEMPHASIS_75_uS; + value = 2;/*V4L2_DEEMPHASIS_75_uS; */ break; default: @@ -564,11 +554,10 @@ __mmradio_set_deemphasis(mm_radio_t* radio) } /* set it to device */ - (radio->vctrl).id = (0x009d0000 | 0x900) +1;//V4L2_CID_TUNE_DEEMPHASIS; + (radio->vctrl).id = (0x009d0000 | 0x900) + 1; /*V4L2_CID_TUNE_DEEMPHASIS; */ (radio->vctrl).value = value; - if (ioctl(radio->radio_fd, VIDIOC_S_CTRL, &(radio->vctrl)) < 0) - { + 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; } @@ -586,19 +575,18 @@ __mmradio_set_deemphasis(mm_radio_t* radio) * Return : zero on success, or negative value with error code *---------------------------------------------------------------------------*/ int -__mmradio_set_band_range(mm_radio_t* radio) +__mmradio_set_band_range(mm_radio_t *radio) { MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); + 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 ) - { + 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; } @@ -609,11 +597,11 @@ __mmradio_set_band_range(mm_radio_t* radio) } int -_mmradio_set_message_callback(mm_radio_t* radio, MMMessageCallback callback, void *user_param) +_mmradio_set_message_callback(mm_radio_t *radio, MMMessageCallback callback, void *user_param) { MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); + MMRADIO_CHECK_INSTANCE(radio); radio->msg_cb = callback; radio->msg_cb_param = user_param; @@ -626,16 +614,16 @@ _mmradio_set_message_callback(mm_radio_t* radio, MMMessageCallback callback, voi } int -_mmradio_get_state(mm_radio_t* radio, int* pState) +_mmradio_get_state(mm_radio_t *radio, int *pState) { int state = 0; MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); - return_val_if_fail( pState, MM_ERROR_INVALID_ARGUMENT ); + MMRADIO_CHECK_INSTANCE(radio); + return_val_if_fail(pState, MM_ERROR_INVALID_ARGUMENT); - state = __mmradio_get_state( radio ); + state = __mmradio_get_state(radio); *pState = state; @@ -645,35 +633,38 @@ _mmradio_get_state(mm_radio_t* radio, int* pState) } int -_mmradio_start(mm_radio_t* radio) +_mmradio_start(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_START ); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_START); MMRADIO_SLOG_DEBUG("now tune to frequency : %d\n", radio->freq); +#ifdef FEATURE_ASM_SUPPORT ret = mmradio_asm_set_state(&radio->sm, ASM_STATE_PLAYING, ASM_RESOURCE_RADIO_TUNNER); - if ( ret ) - { - MMRADIO_LOG_ERROR("failed to set asm state to PLAYING\n"); +#else + ret = mmradio_set_audio_focus(&radio->sm, _mmradio_sound_focus_watch_cb, TRUE, (void *)radio); +#endif + if (ret) { + MMRADIO_LOG_ERROR("failed to set asm state to PLAYING or audio focus\n"); return ret; } /* set stored frequency */ - _mmradio_set_frequency( radio, radio->freq ); + _mmradio_set_frequency(radio, radio->freq); /* unmute */ - if( _mmradio_unmute(radio) != MM_ERROR_NONE) + if (_mmradio_unmute(radio) != MM_ERROR_NONE) return MM_ERROR_RADIO_NOT_INITIALIZED; - MMRADIO_SET_STATE( radio, MM_RADIO_STATE_PLAYING ); + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_PLAYING); #ifdef USE_GST_PIPELINE - ret = _mmradio_start_pipeline( radio ); - if ( ret ) { + ret = _mmradio_start_pipeline(radio); + if (ret) { debug_error("_mmradio_start_pipeline is failed\n"); return ret; } @@ -685,29 +676,30 @@ _mmradio_start(mm_radio_t* radio) } int -_mmradio_stop(mm_radio_t* radio) +_mmradio_stop(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_STOP ); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_STOP); - if( _mmradio_mute(radio) != MM_ERROR_NONE) + if (_mmradio_mute(radio) != MM_ERROR_NONE) return MM_ERROR_RADIO_NOT_INITIALIZED; - MMRADIO_SET_STATE( radio, MM_RADIO_STATE_READY ); + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY); +#ifdef FEATURE_ASM_SUPPORT ret = mmradio_asm_set_state(&radio->sm, ASM_STATE_STOP, ASM_RESOURCE_NONE); - if ( ret ) - { + if (ret) { MMRADIO_LOG_ERROR("failed to set asm state to PLAYING\n"); return ret; } +#endif #ifdef USE_GST_PIPELINE - ret= _mmradio_stop_pipeline( radio ); - if ( ret ) { + ret = _mmradio_stop_pipeline(radio); + if (ret) { debug_error("_mmradio_stop_pipeline is failed\n"); return ret; } @@ -720,37 +712,37 @@ _mmradio_stop(mm_radio_t* radio) #ifdef USE_GST_PIPELINE int -_mmradio_realize_pipeline(mm_radio_t* radio) +_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); + gst_init(NULL, NULL); + radio->pGstreamer_s = g_new0(mm_radio_gstreamer_s, 1); - radio->pGstreamer_s->pipeline= gst_pipeline_new ("avsysaudio"); + radio->pGstreamer_s->pipeline = gst_pipeline_new("fmradio"); - radio->pGstreamer_s->avsysaudiosrc= gst_element_factory_make("avsysaudiosrc","fm audio src"); - radio->pGstreamer_s->queue2= gst_element_factory_make("queue2","queue2"); - radio->pGstreamer_s->avsysaudiosink= gst_element_factory_make("pulsesink","audio sink"); + 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->avsysaudiosrc, "latency", 2, NULL); - g_object_set(radio->pGstreamer_s->avsysaudiosink, "sync", false, NULL); + /* 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->avsysaudiosrc || !radio->pGstreamer_s->queue2 || !radio->pGstreamer_s->avsysaudiosink) { + 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; } gst_bin_add_many(GST_BIN(radio->pGstreamer_s->pipeline), - radio->pGstreamer_s->avsysaudiosrc, - radio->pGstreamer_s->queue2, - radio->pGstreamer_s->avsysaudiosink, - NULL); - if(!gst_element_link_many( - radio->pGstreamer_s->avsysaudiosrc, - radio->pGstreamer_s->queue2, - radio->pGstreamer_s->avsysaudiosink, - NULL)) { + 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; } @@ -758,24 +750,24 @@ _mmradio_realize_pipeline(mm_radio_t* radio) } int -_mmradio_start_pipeline(mm_radio_t* radio) +_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) { + 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); + gst_object_unref(radio->pGstreamer_s->pipeline); + g_free(radio->pGstreamer_s); return MM_ERROR_RADIO_INVALID_STATE; } - ret_state = gst_element_get_state (radio->pGstreamer_s->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); + 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); + 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); @@ -784,24 +776,24 @@ _mmradio_start_pipeline(mm_radio_t* radio) } int -_mmradio_stop_pipeline(mm_radio_t* radio) +_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) { + 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); + gst_object_unref(radio->pGstreamer_s->pipeline); + g_free(radio->pGstreamer_s); return MM_ERROR_RADIO_INVALID_STATE; } - ret_state = gst_element_get_state (radio->pGstreamer_s->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); + 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); + 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); @@ -810,55 +802,54 @@ _mmradio_stop_pipeline(mm_radio_t* radio) } int -_mmradio_destroy_pipeline(mm_radio_t * radio) +_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) { + 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); + gst_object_unref(radio->pGstreamer_s->pipeline); + g_free(radio->pGstreamer_s); return MM_ERROR_RADIO_INVALID_STATE; } - ret_state = gst_element_get_state (radio->pGstreamer_s->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); + 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); + 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); + gst_object_unref(radio->pGstreamer_s->pipeline); + g_free(radio->pGstreamer_s); return ret; } #endif int -_mmradio_seek(mm_radio_t* radio, MMRadioSeekDirectionType direction) +_mmradio_seek(mm_radio_t *radio, MMRadioSeekDirectionType direction) { MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); - MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_SEEK ); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SEEK); - int ret = 0; + int ret = 0; - if( _mmradio_mute(radio) != MM_ERROR_NONE) + if (_mmradio_mute(radio) != MM_ERROR_NONE) return MM_ERROR_RADIO_NOT_INITIALIZED; MMRADIO_SLOG_DEBUG("trying to seek. direction[0:UP/1:DOWN) %d\n", direction); radio->seek_direction = direction; ret = pthread_create(&radio->seek_thread, NULL, - (void *)__mmradio_seek_thread, (void *)radio); + (void *)__mmradio_seek_thread, (void *)radio); - if ( ret ) - { + if (ret) { MMRADIO_LOG_DEBUG("failed create thread\n"); return MM_ERROR_RADIO_INTERNAL; } @@ -869,27 +860,26 @@ _mmradio_seek(mm_radio_t* radio, MMRadioSeekDirectionType direction) } int -_mmradio_start_scan(mm_radio_t* radio) +_mmradio_start_scan(mm_radio_t *radio) { MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); - MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_START_SCAN ); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_START_SCAN); int scan_tr_id = 0; radio->stop_scan = false; scan_tr_id = pthread_create(&radio->scan_thread, NULL, - (void *)__mmradio_scan_thread, (void *)radio); + (void *)__mmradio_scan_thread, (void *)radio); - if (scan_tr_id != 0) - { + if (scan_tr_id != 0) { MMRADIO_LOG_DEBUG("failed to create thread : scan\n"); return MM_ERROR_RADIO_NOT_INITIALIZED; } - MMRADIO_SET_STATE( radio, MM_RADIO_STATE_SCANNING ); + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_SCANNING); MMRADIO_LOG_FLEAVE(); @@ -897,23 +887,22 @@ _mmradio_start_scan(mm_radio_t* radio) } int -_mmradio_stop_scan(mm_radio_t* radio) +_mmradio_stop_scan(mm_radio_t *radio) { MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); - MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_STOP_SCAN ); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_STOP_SCAN); radio->stop_scan = true; - if( radio->scan_thread > 0 ) - { + if (radio->scan_thread > 0) { pthread_cancel(radio->scan_thread); pthread_join(radio->scan_thread, NULL); - radio->scan_thread = 0; + radio->scan_thread = 0; } - MMRADIO_SET_STATE( radio, MM_RADIO_STATE_READY ); + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY); MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_STOP, NULL); MMRADIO_LOG_FLEAVE(); @@ -922,32 +911,30 @@ _mmradio_stop_scan(mm_radio_t* radio) } int -_mm_radio_get_signal_strength(mm_radio_t* radio, int *value) +_mm_radio_get_signal_strength(mm_radio_t *radio, int *value) { MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); + MMRADIO_CHECK_INSTANCE(radio); - return_val_if_fail( value, MM_ERROR_INVALID_ARGUMENT ); + return_val_if_fail(value, MM_ERROR_INVALID_ARGUMENT); /* just return stored frequency if radio device is not ready */ - if ( radio->radio_fd < 0 ) - { + if (radio->radio_fd < 0) { MMRADIO_SLOG_DEBUG("Device not ready so sending 0\n"); *value = 0; return MM_ERROR_NONE; } - if (ioctl(radio->radio_fd, VIDIOC_G_TUNER, &(radio->vt)) < 0) - { + if (ioctl(radio->radio_fd, VIDIOC_G_TUNER, &(radio->vt)) < 0) { debug_error("ioctl VIDIOC_G_TUNER error\n"); return MM_ERROR_RADIO_INTERNAL; } - *value = radio->vt.signal; + *value = radio->vt.signal; MMRADIO_LOG_FLEAVE(); return MM_ERROR_NONE; } void -__mmradio_scan_thread(mm_radio_t* radio) +__mmradio_scan_thread(mm_radio_t *radio) { int ret = 0; int prev_freq = 0; @@ -959,39 +946,33 @@ __mmradio_scan_thread(mm_radio_t* radio) vs.wrap_around = 0; /* around:1 not around:0 */ vs.seek_upward = 1; /* up : 1 ------- down : 0 */ + TTRACE_ASYNCBEGIN("MMRADIO:SCAN_THREAD", radio->radio_fd); MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); - if( _mmradio_mute(radio) != MM_ERROR_NONE) + MMRADIO_CHECK_INSTANCE(radio); + if (_mmradio_mute(radio) != MM_ERROR_NONE) goto FINISHED; - if( _mmradio_set_frequency(radio, radio->region_setting.band_min) != MM_ERROR_NONE) + if (_mmradio_set_frequency(radio, radio->region_setting.band_min) != MM_ERROR_NONE) goto FINISHED; MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_START, NULL); - MMRADIO_SET_STATE( radio, MM_RADIO_STATE_SCANNING ); + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_SCANNING); - while( ! radio->stop_scan ) - { + while (!radio->stop_scan) { int 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 ) - { + if (ret == -1) { + if (errno == EAGAIN) { MMRADIO_LOG_ERROR("scanning timeout\n"); continue; - } - else if ( errno == EINVAL ) - { + } 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 - { + } else { MMRADIO_LOG_ERROR("Error: %s, %d\n", strerror_r(errno, str_error, sizeof(str_error)), errno); break; } @@ -999,35 +980,30 @@ __mmradio_scan_thread(mm_radio_t* radio) /* now we can get new frequency from radio device */ - if ( radio->stop_scan ) break; + if (radio->stop_scan) break; ret = _mmradio_get_frequency(radio, &freq); - if ( ret ) - { + if (ret) { MMRADIO_LOG_ERROR("failed to get current frequency\n"); - } - else - { - if ( freq < prev_freq ) - { + } else { + if (freq < prev_freq) { MMRADIO_LOG_DEBUG("scanning wrapped around. stopping scan\n"); break; } - if ( freq == prev_freq) + if (freq == prev_freq) continue; prev_freq = param.radio_scan.frequency = freq; MMRADIO_SLOG_DEBUG("scanning : new frequency : [%d]\n", param.radio_scan.frequency); /* drop if max freq is scanned */ - if (param.radio_scan.frequency == radio->region_setting.band_max ) - { + if (param.radio_scan.frequency == radio->region_setting.band_max) { MMRADIO_LOG_DEBUG("%d freq is dropping...and stopping scan\n", param.radio_scan.frequency); break; } - if ( radio->stop_scan ) break; // doesn't need to post + if (radio->stop_scan) break; /* doesn't need to post */ MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_INFO, ¶m); } @@ -1035,12 +1011,12 @@ __mmradio_scan_thread(mm_radio_t* radio) FINISHED: radio->scan_thread = 0; - MMRADIO_SET_STATE( radio, MM_RADIO_STATE_READY ); + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY); - if ( ! radio->stop_scan ) - { + if (!radio->stop_scan) { MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_FINISH, NULL); } + TTRACE_ASYNCEND("MMRADIO:SCAN_THREAD", radio->radio_fd); MMRADIO_LOG_FLEAVE(); @@ -1050,13 +1026,13 @@ FINISHED: } bool -__is_tunable_frequency(mm_radio_t* radio, int freq) +__is_tunable_frequency(mm_radio_t *radio, int freq) { MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); + 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(); @@ -1065,7 +1041,7 @@ __is_tunable_frequency(mm_radio_t* radio, int freq) } void -__mmradio_seek_thread(mm_radio_t* radio) +__mmradio_seek_thread(mm_radio_t *radio) { int ret = 0; int freq = 0; @@ -1078,12 +1054,12 @@ __mmradio_seek_thread(mm_radio_t* radio) vs.type = V4L2_TUNER_RADIO; vs.wrap_around = DEFAULT_WRAP_AROUND; + TTRACE_ASYNCBEGIN("MMRADIO:SEEK_THREAD", radio->radio_fd); MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); + MMRADIO_CHECK_INSTANCE(radio); /* check direction */ - switch( radio->seek_direction ) - { + switch (radio->seek_direction) { case MM_RADIO_SEEK_UP: vs.seek_upward = 1; break; @@ -1096,25 +1072,18 @@ __mmradio_seek_thread(mm_radio_t* radio) MMRADIO_LOG_DEBUG("seeking....\n"); - while ( ! seek_stop ) - { - ret = ioctl( radio->radio_fd, VIDIOC_S_HW_FREQ_SEEK, &vs ); + while (!seek_stop) { + ret = ioctl(radio->radio_fd, VIDIOC_S_HW_FREQ_SEEK, &vs); - if( ret == -1 ) - { - if ( errno == EAGAIN ) - { + 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 ) - { + } 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 - { + } else { MMRADIO_LOG_ERROR("Error: %s, %d\n", strerror_r(errno, str_error, sizeof(str_error)), errno); goto SEEK_FAILED; } @@ -1122,8 +1091,7 @@ __mmradio_seek_thread(mm_radio_t* radio) /* now we can get new frequency from radio device */ ret = _mmradio_get_frequency(radio, &freq); - if ( ret ) - { + if (ret) { MMRADIO_LOG_ERROR("failed to get current frequency\n"); goto SEEK_FAILED; } @@ -1131,18 +1099,15 @@ __mmradio_seek_thread(mm_radio_t* radio) MMRADIO_LOG_DEBUG("found frequency\n"); /* if same freq is found, ignore it and search next one. */ - if ( freq == radio->prev_seek_freq ) - { + if (freq == radio->prev_seek_freq) { MMRADIO_LOG_DEBUG("It's same with previous found one. So, trying next one. \n"); continue; } - if ( __is_tunable_frequency(radio, freq) ) // check if it's limit freq or not - { + if (__is_tunable_frequency(radio, freq)) { /* check if it's limit freq or not */ /* now tune to new frequency */ ret = _mmradio_set_frequency(radio, freq); - if ( ret ) - { + if (ret) { MMRADIO_LOG_ERROR("failed to tune to new frequency\n"); goto SEEK_FAILED; } @@ -1153,8 +1118,7 @@ __mmradio_seek_thread(mm_radio_t* radio) * Otherwise, sound can't output even though application set new frequency. */ ret = _mmradio_unmute(radio); - if ( ret ) - { + if (ret) { MMRADIO_LOG_ERROR("failed to tune to new frequency\n"); goto SEEK_FAILED; } @@ -1166,7 +1130,7 @@ __mmradio_seek_thread(mm_radio_t* radio) } radio->seek_thread = 0; - + TTRACE_ASYNCEND("MMRADIO:SEEK_THREAD", radio->radio_fd); MMRADIO_LOG_FLEAVE(); pthread_exit(NULL); @@ -1177,18 +1141,18 @@ SEEK_FAILED: param.radio_scan.frequency = -1; MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, ¶m); pthread_exit(NULL); + TTRACE_ASYNCEND("MMRADIO:SEEK_THREAD", radio->radio_fd); return; } static bool -__mmradio_post_message(mm_radio_t* radio, enum MMMessageType msgtype, MMMessageParamType* param) +__mmradio_post_message(mm_radio_t *radio, enum MMMessageType msgtype, MMMessageParamType *param) { - MMRADIO_CHECK_INSTANCE( radio ); + MMRADIO_CHECK_INSTANCE(radio); MMRADIO_LOG_FENTER(); - if ( !radio->msg_cb ) - { + if (!radio->msg_cb) { debug_warning("failed to post a message\n"); return false; } @@ -1203,158 +1167,145 @@ __mmradio_post_message(mm_radio_t* radio, enum MMMessageType msgtype, MMMessageP } static int - __mmradio_check_state(mm_radio_t* radio, MMRadioCommand command) - { - MMRadioStateType radio_state = MM_RADIO_STATE_NUM; +__mmradio_check_state(mm_radio_t *radio, MMRadioCommand command) +{ + MMRadioStateType radio_state = MM_RADIO_STATE_NUM; MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); - - radio_state = __mmradio_get_state( radio ); - - MMRADIO_LOG_DEBUG("incomming command : %d current state : %d\n", command, radio_state); - - switch( command ) - { - case MMRADIO_COMMAND_CREATE: - { - if ( radio_state != 0 ) - goto NO_OP; - } - break; - - case MMRADIO_COMMAND_REALIZE: - { - if ( radio_state == MM_RADIO_STATE_READY || - radio_state == MM_RADIO_STATE_PLAYING || - radio_state == MM_RADIO_STATE_SCANNING ) - goto NO_OP; - - if ( radio_state == 0 ) - goto INVALID_STATE; - } - break; - - case MMRADIO_COMMAND_UNREALIZE: - { - if ( radio_state == MM_RADIO_STATE_NULL ) - goto NO_OP; - - /* we can call unrealize at any higher state */ - } - break; - - case MMRADIO_COMMAND_START: - { - if ( radio_state == MM_RADIO_STATE_PLAYING ) - goto NO_OP; - - if ( radio_state != MM_RADIO_STATE_READY ) - goto INVALID_STATE; - } - break; - - case MMRADIO_COMMAND_STOP: - { - if ( radio_state == MM_RADIO_STATE_READY ) - goto NO_OP; - - if ( radio_state != MM_RADIO_STATE_PLAYING ) - goto INVALID_STATE; - } - break; - - case MMRADIO_COMMAND_START_SCAN: - { - if ( radio_state == MM_RADIO_STATE_SCANNING ) - goto NO_OP; - - if ( radio_state != MM_RADIO_STATE_READY ) - goto INVALID_STATE; - } - break; - - case MMRADIO_COMMAND_STOP_SCAN: - { - if ( radio_state == MM_RADIO_STATE_READY ) - goto NO_OP; - - if ( radio_state != MM_RADIO_STATE_SCANNING ) - goto INVALID_STATE; - } - break; - - case MMRADIO_COMMAND_DESTROY: - case MMRADIO_COMMAND_MUTE: - case MMRADIO_COMMAND_UNMUTE: - case MMRADIO_COMMAND_SET_FREQ: - case MMRADIO_COMMAND_GET_FREQ: - case MMRADIO_COMMAND_SET_REGION: - { - /* we can do it at any state */ - } - break; - - case MMRADIO_COMMAND_SEEK: - { - if ( radio_state != MM_RADIO_STATE_PLAYING ) - goto INVALID_STATE; - } - break; - - case MMRADIO_COMMAND_GET_REGION: - { - if ( radio_state == MM_RADIO_STATE_NULL ) - goto INVALID_STATE; - } - break; + MMRADIO_CHECK_INSTANCE(radio); + + radio_state = __mmradio_get_state(radio); + + MMRADIO_LOG_DEBUG("incomming command : %d current state : %d\n", command, radio_state); + + switch (command) { + case MMRADIO_COMMAND_CREATE: { + if (radio_state != 0) + goto NO_OP; + } + break; + + case MMRADIO_COMMAND_REALIZE: { + if (radio_state == MM_RADIO_STATE_READY || + radio_state == MM_RADIO_STATE_PLAYING || + radio_state == MM_RADIO_STATE_SCANNING) + goto NO_OP; + + if (radio_state == 0) + goto INVALID_STATE; + } + break; + + case MMRADIO_COMMAND_UNREALIZE: { + if (radio_state == MM_RADIO_STATE_NULL) + goto NO_OP; + + /* we can call unrealize at any higher state */ + } + break; + + case MMRADIO_COMMAND_START: { + if (radio_state == MM_RADIO_STATE_PLAYING) + goto NO_OP; + + if (radio_state != MM_RADIO_STATE_READY) + goto INVALID_STATE; + } + break; + + case MMRADIO_COMMAND_STOP: { + if (radio_state == MM_RADIO_STATE_READY) + goto NO_OP; + + if (radio_state != MM_RADIO_STATE_PLAYING) + goto INVALID_STATE; + } + break; + + case MMRADIO_COMMAND_START_SCAN: { + if (radio_state == MM_RADIO_STATE_SCANNING) + goto NO_OP; + + if (radio_state != MM_RADIO_STATE_READY) + goto INVALID_STATE; + } + break; + + case MMRADIO_COMMAND_STOP_SCAN: { + if (radio_state == MM_RADIO_STATE_READY) + goto NO_OP; + + if (radio_state != MM_RADIO_STATE_SCANNING) + goto INVALID_STATE; + } + break; + + case MMRADIO_COMMAND_DESTROY: + case MMRADIO_COMMAND_MUTE: + case MMRADIO_COMMAND_UNMUTE: + case MMRADIO_COMMAND_SET_FREQ: + case MMRADIO_COMMAND_GET_FREQ: + case MMRADIO_COMMAND_SET_REGION: { + /* we can do it at any state */ + } + break; + + case MMRADIO_COMMAND_SEEK: { + if (radio_state != MM_RADIO_STATE_PLAYING) + goto INVALID_STATE; + } + break; - default: - MMRADIO_LOG_DEBUG("not handled in FSM. don't care it\n"); - break; - } + case MMRADIO_COMMAND_GET_REGION: { + if (radio_state == MM_RADIO_STATE_NULL) + goto INVALID_STATE; + } + break; + + default: + MMRADIO_LOG_DEBUG("not handled in FSM. don't care it\n"); + break; + } - MMRADIO_LOG_DEBUG("status OK\n"); + MMRADIO_LOG_DEBUG("status OK\n"); - radio->cmd = command; + radio->cmd = command; MMRADIO_LOG_FLEAVE(); - return MM_ERROR_NONE; + return MM_ERROR_NONE; - INVALID_STATE: - debug_warning("invalid state. current : %d command : %d\n", - radio_state, command); +INVALID_STATE: + debug_warning("invalid state. current : %d command : %d\n", + radio_state, command); MMRADIO_LOG_FLEAVE(); - return MM_ERROR_RADIO_INVALID_STATE; + return MM_ERROR_RADIO_INVALID_STATE; - NO_OP: - debug_warning("mm-radio is in the desired state(%d). doing noting\n", radio_state); +NO_OP: + debug_warning("mm-radio is in the desired state(%d). doing noting\n", radio_state); MMRADIO_LOG_FLEAVE(); - return MM_ERROR_RADIO_NO_OP; + return MM_ERROR_RADIO_NO_OP; - } +} static bool -__mmradio_set_state(mm_radio_t* radio, int new_state) +__mmradio_set_state(mm_radio_t *radio, int new_state) { MMMessageParamType msg = {0, }; int msg_type = MM_MESSAGE_UNKNOWN; MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); + MMRADIO_CHECK_INSTANCE(radio); - if ( ! radio ) - { + if (!radio) { debug_warning("calling set_state with invalid radio handle\n"); return false; } - if ( radio->current_state == new_state && radio->pending_state == 0 ) - { + if (radio->current_state == new_state && radio->pending_state == 0) { debug_warning("we are in same state\n"); return true; } @@ -1368,27 +1319,24 @@ __mmradio_set_state(mm_radio_t* radio, int new_state) msg.state.current = radio->current_state; /* post message to application */ - switch( radio->sm.by_asm_cb ) - { - case MMRADIO_ASM_CB_NONE: - { - msg_type = MM_MESSAGE_STATE_CHANGED; - MMRADIO_POST_MSG( radio, msg_type, &msg ); - } - break; - - case MMRADIO_ASM_CB_POSTMSG: - { - msg_type = MM_MESSAGE_STATE_INTERRUPTED; - msg.union_type = MM_MSG_UNION_CODE; - msg.code = radio->sm.event_src; - MMRADIO_POST_MSG( radio, msg_type, &msg ); - } - break; + switch (radio->sm.by_asm_cb) { + case MMRADIO_ASM_CB_NONE: { + msg_type = MM_MESSAGE_STATE_CHANGED; + MMRADIO_POST_MSG(radio, msg_type, &msg); + } + break; + + case MMRADIO_ASM_CB_POSTMSG: { + msg_type = MM_MESSAGE_STATE_INTERRUPTED; + msg.union_type = MM_MSG_UNION_CODE; + msg.code = radio->sm.event_src; + MMRADIO_POST_MSG(radio, msg_type, &msg); + } + break; case MMRADIO_ASM_CB_SKIP_POSTMSG: default: - break; + break; } MMRADIO_LOG_FLEAVE(); @@ -1397,20 +1345,20 @@ __mmradio_set_state(mm_radio_t* radio, int new_state) } static int -__mmradio_get_state(mm_radio_t* radio) +__mmradio_get_state(mm_radio_t *radio) { - MMRADIO_CHECK_INSTANCE( radio ); + MMRADIO_CHECK_INSTANCE(radio); MMRADIO_LOG_DEBUG("radio state : current : [%d] old : [%d] pending : [%d]\n", - radio->current_state, radio->old_state, radio->pending_state ); + radio->current_state, radio->old_state, radio->pending_state); return radio->current_state; } - +#ifdef FEATURE_ASM_SUPPORT ASM_cb_result_t -__mmradio_asm_callback(int handle, ASM_event_sources_t event_source, ASM_sound_commands_t command, unsigned int sound_status, void* cb_data) +__mmradio_asm_callback(int handle, ASM_event_sources_t event_source, ASM_sound_commands_t command, unsigned int sound_status, void *cb_data) { - mm_radio_t* radio = (mm_radio_t*) cb_data; + mm_radio_t *radio = (mm_radio_t *) cb_data; int result = MM_ERROR_NONE; ASM_cb_result_t cb_res = ASM_CB_RES_NONE; @@ -1418,77 +1366,161 @@ __mmradio_asm_callback(int handle, ASM_event_sources_t event_source, ASM_sound_c radio->sm.event_src = event_source; - switch(command) - { + switch (command) { case ASM_COMMAND_STOP: - case ASM_COMMAND_PAUSE: - { - MMRADIO_LOG_DEBUG("ASM asked me to stop. cmd : %d\n", command); - switch(event_source) - { - case ASM_EVENT_SOURCE_CALL_START: - case ASM_EVENT_SOURCE_ALARM_START: - case ASM_EVENT_SOURCE_EARJACK_UNPLUG: - case ASM_EVENT_SOURCE_MEDIA: - { - radio->sm.by_asm_cb = MMRADIO_ASM_CB_POSTMSG; - result = _mmradio_stop(radio); - if( result ) - { - MMRADIO_LOG_ERROR("failed to stop radio\n"); - } - - MMRADIO_LOG_DEBUG("skip unrealize in asm callback"); - } - break; - - case ASM_EVENT_SOURCE_RESOURCE_CONFLICT: - default: - { - radio->sm.by_asm_cb = MMRADIO_ASM_CB_POSTMSG; - result = _mmradio_stop(radio); - if( result ) - { - MMRADIO_LOG_ERROR("failed to stop radio\n"); - } + case ASM_COMMAND_PAUSE: { + MMRADIO_LOG_DEBUG("ASM asked me to stop. cmd : %d\n", command); + switch (event_source) { + case ASM_EVENT_SOURCE_CALL_START: + case ASM_EVENT_SOURCE_ALARM_START: + case ASM_EVENT_SOURCE_EARJACK_UNPLUG: + case ASM_EVENT_SOURCE_MEDIA: { + radio->sm.by_asm_cb = MMRADIO_ASM_CB_POSTMSG; + result = _mmradio_stop(radio); + if (result) { + MMRADIO_LOG_ERROR("failed to stop radio\n"); + } + + MMRADIO_LOG_DEBUG("skip unrealize in asm callback"); + } + break; + + case ASM_EVENT_SOURCE_RESOURCE_CONFLICT: + default: { + radio->sm.by_asm_cb = MMRADIO_ASM_CB_POSTMSG; + result = _mmradio_stop(radio); + if (result) { + MMRADIO_LOG_ERROR("failed to stop radio\n"); + } + } + break; } - break; + cb_res = ASM_CB_RES_STOP; } - cb_res = ASM_CB_RES_STOP; - } - break; + break; case ASM_COMMAND_PLAY: - case ASM_COMMAND_RESUME: - { - MMMessageParamType msg = {0,}; - msg.union_type = MM_MSG_UNION_CODE; - msg.code = event_source; + case ASM_COMMAND_RESUME: { + MMMessageParamType msg = {0,}; + msg.union_type = MM_MSG_UNION_CODE; + msg.code = event_source; - MMRADIO_LOG_DEBUG("Got ASM resume message by %d\n", msg.code); - MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg); + MMRADIO_LOG_DEBUG("Got ASM resume message by %d\n", msg.code); + MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg); - cb_res = ASM_CB_RES_IGNORE; - radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE; - } - break; + cb_res = ASM_CB_RES_IGNORE; + radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE; + } + break; default: - break; + break; } MMRADIO_LOG_FLEAVE(); return cb_res; } +#else +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, + const char *additional_info, void *user_data) +{ + mm_radio_t *radio = (mm_radio_t *) user_data; + ASM_event_sources_t event_source; + int result = MM_ERROR_NONE; + int postMsg = false; + + MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_INSTANCE(radio); -int _mmradio_get_region_type(mm_radio_t*radio, MMRadioRegionType *type) + mmradio_get_audio_focus_reason(focus_state, reason_for_change, &event_source, &postMsg); + radio->sm.event_src = event_source; + + switch (focus_state) { + case FOCUS_IS_RELEASED: + radio->sm.by_asm_cb = MMRADIO_ASM_CB_POSTMSG; + result = _mmradio_stop(radio); + if (result) { + MMRADIO_LOG_ERROR("failed to stop radio\n"); + } + MMRADIO_LOG_DEBUG("FOCUS_IS_RELEASED\n"); + break; + + case FOCUS_IS_ACQUIRED: { + MMMessageParamType msg = {0,}; + msg.union_type = MM_MSG_UNION_CODE; + msg.code = event_source; + if (postMsg) + MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg); + + radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE; + + MMRADIO_LOG_DEBUG("FOCUS_IS_ACQUIRED\n"); + } + break; + + default: + MMRADIO_LOG_DEBUG("Unknown focus_state\n"); + break; + } + MMRADIO_LOG_FLEAVE(); +} + +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; + ASM_event_sources_t event_source; + int result = MM_ERROR_NONE; + int postMsg = false; + MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); - MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_GET_REGION ); + MMRADIO_CHECK_INSTANCE(radio); + + mmradio_get_audio_focus_reason(!focus_state, reason_for_change, &event_source, &postMsg); + radio->sm.event_src = event_source; + + switch (focus_state) { + case FOCUS_IS_RELEASED: { + MMMessageParamType msg = {0,}; + msg.union_type = MM_MSG_UNION_CODE; + msg.code = event_source; + if (postMsg) + MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg); + + radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE; - return_val_if_fail( type, MM_ERROR_INVALID_ARGUMENT ); + MMRADIO_LOG_DEBUG("FOCUS_IS_ACQUIRED postMsg: %d\n", postMsg); + } + break; + + case FOCUS_IS_ACQUIRED: { + radio->sm.by_asm_cb = MMRADIO_ASM_CB_POSTMSG; + result = _mmradio_stop(radio); + if (result) { + MMRADIO_LOG_ERROR("failed to stop radio\n"); + } + MMRADIO_LOG_DEBUG("FOCUS_IS_RELEASED\n"); + break; + } + break; + + default: + MMRADIO_LOG_DEBUG("Unknown focus_state postMsg : %d\n", postMsg); + break; + } + MMRADIO_LOG_FLEAVE(); +} +#endif + +int _mmradio_get_region_type(mm_radio_t *radio, MMRadioRegionType *type) +{ + MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION); + + return_val_if_fail(type, MM_ERROR_INVALID_ARGUMENT); *type = radio->region_setting.country; @@ -1496,13 +1528,13 @@ int _mmradio_get_region_type(mm_radio_t*radio, MMRadioRegionType *type) return MM_ERROR_NONE; } -int _mmradio_get_region_frequency_range(mm_radio_t* radio, unsigned int *min_freq, unsigned int *max_freq) +int _mmradio_get_region_frequency_range(mm_radio_t *radio, unsigned int *min_freq, unsigned int *max_freq) { MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); - MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_GET_REGION ); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION); - return_val_if_fail( min_freq && max_freq, MM_ERROR_INVALID_ARGUMENT ); + return_val_if_fail(min_freq && max_freq, MM_ERROR_INVALID_ARGUMENT); *min_freq = radio->region_setting.band_min; *max_freq = radio->region_setting.band_max; @@ -1510,3 +1542,19 @@ int _mmradio_get_region_frequency_range(mm_radio_t* radio, unsigned int *min_fre MMRADIO_LOG_FLEAVE(); return MM_ERROR_NONE; } + +int _mmradio_get_channel_spacing(mm_radio_t *radio, unsigned int *ch_spacing) +{ + MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION); + + return_val_if_fail(ch_spacing, MM_ERROR_INVALID_ARGUMENT); + + *ch_spacing = radio->region_setting.channel_spacing; + + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_NONE; +} + + diff --git a/src/mm_radio_priv_brcm.c b/src/mm_radio_priv_brcm.c new file mode 100755 index 0000000..51e6624 --- /dev/null +++ b/src/mm_radio_priv_brcm.c @@ -0,0 +1,2987 @@ +/* + * libmm-radio + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: JongHyuk Choi , YoungHwan An + * + * 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 FILES | +| | +========================================================================================== */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + + +#include "mm_radio_priv_common.h" +#include "mm_radio_priv_v4l2.h" + +#define MM_RADIO_EAR_PHONE_POLICY + +/*=========================================================================================== +note: This File is specific to fm devices based on v4l2 +============================================================================================*/ + +/*=========================================================================================== + LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE +========================================================================================== */ +/*--------------------------------------------------------------------------- + GLOBAL CONSTANT DEFINITIONS: +---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + IMPORTED VARIABLE DECLARATIONS: +---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + IMPORTED FUNCTION DECLARATIONS: +---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + LOCAL #defines: +---------------------------------------------------------------------------*/ +#define DEFAULT_DEVICE "/dev/radio0" +#define TUNER_INDEX 0 + +#define DEFAULT_FREQ 107700 + +#define FREQ_FRAC 16 +#define RADIO_FREQ_FORMAT_SET(x_freq) ((x_freq) * FREQ_FRAC) +#define RADIO_FREQ_FORMAT_GET(x_freq) ((x_freq) / FREQ_FRAC) +#define DEFAULT_WRAP_AROUND 1 /*If non-zero, wrap around when at the end of the frequency range, else stop seeking */ + +#define RADIO_DEFAULT_REGION MM_RADIO_REGION_GROUP_EUROPE + +#define FM_VOLUME_BASE 30 +#define FM_VOLUME_MAX 16 +static int fm_volume_tbl[FM_VOLUME_MAX] = { + 0, 2, 4, 8, 15, 30, 45, 70, 80, 100, 125, 150, 180, 210, 230, 255 +}; + +#define BT_ENABLE "/var/run/bluetooth/bt" +#define DEVICE_CLOSE_RETRY_CNT 10 +#define HCI_DISABLE_RETRY_CNT 100 + +/*--------------------------------------------------------------------------- + LOCAL CONSTANT DEFINITIONS: +---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + LOCAL DATA TYPE DEFINITIONS: +---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + GLOBAL VARIABLE DEFINITIONS: +---------------------------------------------------------------------------*/ +extern int errno; + +/*--------------------------------------------------------------------------- + LOCAL VARIABLE DEFINITIONS: +---------------------------------------------------------------------------*/ +/* radio region configuration table */ +static const MMRadioRegion_t region_table[] = { + { /* Notrh America, South America, South Korea, Taiwan, Australia */ + MM_RADIO_REGION_GROUP_USA, /* region type */ + MM_RADIO_DEEMPHASIS_75_US, /* de-emphasis */ + MM_RADIO_FREQ_MIN_87500_KHZ, /* min freq. */ + MM_RADIO_FREQ_MAX_108000_KHZ, /* max freq. */ + 50, + }, + { /* China, Europe, Africa, Middle East, Hong Kong, India, Indonesia, Russia, Singapore */ + MM_RADIO_REGION_GROUP_EUROPE, + MM_RADIO_DEEMPHASIS_50_US, + MM_RADIO_FREQ_MIN_87500_KHZ, + MM_RADIO_FREQ_MAX_108000_KHZ, + 50, + }, + { + MM_RADIO_REGION_GROUP_JAPAN, + MM_RADIO_DEEMPHASIS_50_US, + MM_RADIO_FREQ_MIN_76100_KHZ, + MM_RADIO_FREQ_MAX_89900_KHZ, + 50, + }, +}; +/*--------------------------------------------------------------------------- + LOCAL FUNCTION PROTOTYPES: +---------------------------------------------------------------------------*/ +static bool __mmradio_post_message(mm_radio_t *radio, enum MMMessageType msgtype, MMMessageParamType *param); +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); +static void __mmradio_seek_thread(mm_radio_t *radio); +static void __mmradio_scan_thread(mm_radio_t *radio); +#ifdef FEATURE_ASM_SUPPORT +static ASM_cb_result_t __mmradio_asm_callback(int handle, ASM_event_sources_t sound_event, ASM_sound_commands_t command, unsigned int sound_status, void *cb_data); +#else +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, const char *additional_info, void *user_data); +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 +static bool __is_tunable_frequency(mm_radio_t *radio, int freq); +static int __mmradio_set_band_range(mm_radio_t *radio); +static void __mmradio_volume_change_cb(volume_type_t type, unsigned int volume, void *user_data); +/* FIXME: for checking device is changed. This can be removed with another solution from sound-server */ +static void __mmradio_active_device_changed_cb(mm_sound_device_in device_in, mm_sound_device_out device_out, void *user_data); +static int __mmradio_set_volume(mm_radio_t *radio, unsigned int value); +static int __mmradio_get_volume(mm_radio_t *radio, unsigned int *value); +static int __mmradio_enable_bluetooth(mm_radio_t *radio, int enable); +static int __mmradio_wait_bluetooth_ready(mm_radio_t *radio, int wait_active, int retry_count); + + +static int __mmradio_init_v4l2_device(mm_radio_t *radio); +static void __mmradio_deinit_v4l2_device(mm_radio_t *radio); +static int __mm_radio_rds_callback(int type, void *data, void *user_data); +int _mmradio_pause(mm_radio_t *radio); + +static void _mmradio_fadevolume_cancel(mm_radio_t *radio); +static int _mm_radio_recording_volume_change_policy(mm_radio_t *radio, int present_volume); + +static void __mmradio_event_thread(mm_radio_t *radio); + +/*=========================================================================== + 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 + *---------------------------------------------------------------------------*/ +int _mmradio_apply_region(mm_radio_t *radio, MMRadioRegionType region, bool update) +{ + int count = 0; + int index = 0; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_REGION); + + /* if needed, radio region must be updated. + * Otherwise, just applying settings to device without it. + */ + if (update) { + count = ARRAY_SIZE(region_table); + + /*TODO: if auto is supported...get the region info. here */ + + /* update radio region settings */ + for (index = 0; index < count; index++) { + /* find the region from pre-defined table*/ + if (region_table[index].country == region) { + radio->region_setting.country = region_table[index].country; + radio->region_setting.deemphasis = region_table[index].deemphasis; + radio->region_setting.band_min = region_table[index].band_min; + radio->region_setting.band_max = region_table[index].band_max; + radio->region_setting.channel_spacing = region_table[index].channel_spacing; + } + } + } + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; +} + +int _mmradio_prepare_device(mm_radio_t *radio) +{ + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_INSTANCE(radio); + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE(priv_sprd_v4l2); + + if (!priv_sprd_v4l2->device_ready) { + /*Only check blue-tooth - As this is not a reference count we need not care about the number of calls to enable */ + if (MM_ERROR_NONE != __mmradio_enable_bluetooth(radio, MM_RADIO_TRUE)) { + MMRADIO_LOG_ERROR("__mmradio_enable_bluetooth is failed\n"); + return MM_ERROR_RADIO_DEVICE_NOT_OPENED; + } + + if (MM_ERROR_NONE != __mmradio_wait_bluetooth_ready(radio, MM_RADIO_TRUE, 50)) { + MMRADIO_LOG_ERROR("__mmradio_wait_bluetooth_ready is failed\n"); + return MM_ERROR_RADIO_DEVICE_NOT_OPENED; + } + } else { + MMRADIO_LOG_INFO("HCI attach is already started"); + } + priv_sprd_v4l2->device_ready = MM_RADIO_TRUE; + + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_NONE; +} + +void _mmradio_unprepare_device(mm_radio_t *radio) +{ + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio); + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE_RETURN_VOID(priv_sprd_v4l2); + + /*This is done locked here becuase pause and stop doesn't contain unprepare and is handeled seperatly*/ + pthread_mutex_lock(&radio->state_mutex); + + if (radio->radio_fd < 0) { + if (priv_sprd_v4l2->device_ready) { + MMRADIO_LOG_INFO("try to __mmradio_enable_bluetooth (disable)\n"); + if (MM_ERROR_NONE != __mmradio_enable_bluetooth(radio, FALSE)) { + MMRADIO_LOG_ERROR("__mmradio_enable_bluetooth (disable) is failed\n"); + } else { + /* FIXME: if there is /var/run/bluetooth/bt, BT is enabled. */ + int bt_disabled = 0; + int try_cnt = 0; +bt_check_again: + bt_disabled = access(BT_ENABLE, F_OK); + if (bt_disabled == 0) { + MMRADIO_LOG_INFO("BT is enabled. we will not wait hci disable."); + /* FIXME: we should add some logic for waiting FM close itself later */ + } else { + int ret = MM_ERROR_NONE; + /* fopen BT failed. it means that we should wait hci attach disabled completely */ + MMRADIO_LOG_DEBUG("BT disabled. (%s:%d). Try to disable hci attach", strerror(errno), errno); + ret = __mmradio_wait_bluetooth_ready(radio, MM_RADIO_FALSE, 1); + if (ret == MM_ERROR_RADIO_INVALID_STATE) { + try_cnt++; + if (try_cnt <= HCI_DISABLE_RETRY_CNT) { + MMRADIO_LOG_INFO("still hci attach is Active. Try again (%d/%d)", try_cnt, HCI_DISABLE_RETRY_CNT); + goto bt_check_again; + } + } + } + usleep(200 * 1000); /* FIXME: sleep 200 ms for waiting hci disable in broadcom */ + MMRADIO_LOG_INFO("__mmradio_enable_bluetooth (disable) is success\n"); + } + priv_sprd_v4l2->device_ready = MM_RADIO_FALSE; + } else { + MMRADIO_LOG_INFO("HCI attach is already stopped"); + } + } else { + MMRADIO_LOG_WARNING("radio_fd(%d) still opened. can not disable bluetooth now", radio->radio_fd); + } + + pthread_mutex_unlock(&radio->state_mutex); +} + +int _mmradio_create_radio(mm_radio_t *radio) +{ + int ret = 0; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_CREATE); + + /* set default value */ + radio->radio_fd = -1; + radio->freq = DEFAULT_FREQ; + + memset(&radio->region_setting, 0, sizeof(MMRadioRegion_t)); + + /*allocate memory for chipset specific attributes*/ + radio->vender_specific_handle = (MMRadioVenderHandle) malloc(sizeof(mm_radio_priv_v4l2_t)); + if (!radio->vender_specific_handle) { + MMRADIO_LOG_CRITICAL("cannot allocate memory for mm_radio_priv_sprd_t\n"); + return MM_ERROR_RADIO_NO_FREE_SPACE; + } + memset(radio->vender_specific_handle, 0, sizeof(mm_radio_priv_v4l2_t)); + + /* create command lock */ + ret = pthread_mutex_init(&radio->cmd_lock, NULL); + if (ret) { + MMRADIO_LOG_ERROR("mutex creation failed\n"); + return MM_ERROR_RADIO_INTERNAL; + } + + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_NULL); + +#ifdef FEATURE_ASM_SUPPORT + /* register to ASM */ + ret = mmradio_asm_register(&radio->sm, __mmradio_asm_callback, (void *)radio); +#else + ret = mmradio_audio_focus_register(&radio->sm, _mmradio_sound_focus_cb, (void *)radio); +#endif + if (ret) { + /* NOTE : we are dealing it as an error since we cannot expect it's behavior */ + MMRADIO_LOG_ERROR("failed to register asm server\n"); + return MM_ERROR_RADIO_INTERNAL; + } + radio->event_queue = g_async_queue_new(); + if (!radio->event_queue) { + MMRADIO_LOG_ERROR("failed to get g_async_queue_new \n"); + return MM_ERROR_RADIO_INTERNAL; + } + + ret = pthread_create(&radio->event_thread, NULL, (void *)__mmradio_event_thread, (void *)radio); + if (ret) { + /* NOTE : we are dealing it as an error since we cannot expect it's behavior */ + MMRADIO_LOG_ERROR("failed to register asm server\n"); + return MM_ERROR_RADIO_INTERNAL; + } + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; +} + +int __mmradio_init_v4l2_device(mm_radio_t *radio) +{ + int ret = MM_ERROR_NONE; + int try_count = DEV_OPEN_RETRY_COUNT; + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE(priv_sprd_v4l2); + /* open radio device */ + if (radio->radio_fd < 0) { + MMRadioRegionType region = MM_RADIO_REGION_GROUP_NONE; + bool update = MM_RADIO_FALSE; +try_again: + /* open device */ + radio->radio_fd = open(DEFAULT_DEVICE, O_RDONLY | O_CLOEXEC); + if (radio->radio_fd < 0) { + MMRADIO_LOG_ERROR("failed to open radio device[%s] because of %s(%d)\n", + DEFAULT_DEVICE, strerror(errno), errno); + /* check error */ + switch (errno) { + case ENOENT: + ret = MM_ERROR_RADIO_DEVICE_NOT_FOUND; + goto error; + case EACCES: + ret = MM_ERROR_RADIO_PERMISSION_DENIED; + goto error; + case EBUSY: + ret = MM_ERROR_RADIO_DEVICE_NOT_OPENED; + goto error; + case EAGAIN: + if (try_count > 0) { + try_count--; + MMRADIO_LOG_ERROR("Kernel asked me to try again!!! lets try %d more time(s)", try_count); + /*we make device as not ready because if it was we would not get here*/ + priv_sprd_v4l2->device_ready = MM_RADIO_FALSE; + ret = _mmradio_prepare_device(radio); + if (ret) { + MMRADIO_LOG_ERROR("Coundn't prepare the device - 0x%x\n", ret); + goto error; + } + goto try_again; + } else { + MMRADIO_LOG_ERROR("Out of luck!! we return MM_ERROR_RADIO_DEVICE_NOT_OPENED error"); + ret = MM_ERROR_RADIO_DEVICE_NOT_OPENED; + goto error; + } + default: + ret = MM_ERROR_RADIO_DEVICE_NOT_OPENED; + goto error; + } + } + MMRADIO_LOG_DEBUG("radio device fd = %d\n", radio->radio_fd); + + /* query radio device capabilities. */ + if (ioctl(radio->radio_fd, VIDIOC_QUERYCAP, &(priv_sprd_v4l2->vc)) < 0) { + MMRADIO_LOG_ERROR("VIDIOC_QUERYCAP failed!%s\n", strerror(errno)); + goto error; + } + + if (!(priv_sprd_v4l2->vc.capabilities & V4L2_CAP_TUNER)) { + MMRADIO_LOG_ERROR("this system can't support fm-radio!\n"); + goto error; + } + + /* set tuner audio mode */ + ret = ioctl(radio->radio_fd, VIDIOC_G_TUNER, &(priv_sprd_v4l2->vt)); + if (ret < 0) { + MMRADIO_LOG_ERROR("VIDIOC_G_TUNER failed with %s", strerror(errno)); + goto error; + } + + if (!((priv_sprd_v4l2->vt).capability & V4L2_TUNER_CAP_STEREO)) { + MMRADIO_LOG_ERROR("this system can support mono!\n"); + (priv_sprd_v4l2->vt).audmode = V4L2_TUNER_MODE_MONO; + } else { + (priv_sprd_v4l2->vt).audmode = V4L2_TUNER_MODE_STEREO; + } + + /* set tuner index. Must be 0. */ + (priv_sprd_v4l2->vt).index = TUNER_INDEX; + ret = ioctl(radio->radio_fd, VIDIOC_S_TUNER, &(priv_sprd_v4l2->vt)); + if (ret < 0) { + MMRADIO_LOG_ERROR("VIDIOC_S_TUNER failed with %s", strerror(errno)); + goto error; + } + + + 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 band range to device */ + ret = __mmradio_set_band_range(radio); + MMRADIO_CHECK_GOTO_IF_FAIL(ret, "set band range", error); + } + + return ret; +error: + __mmradio_deinit_v4l2_device(radio); + return ret; +} + +void __mmradio_deinit_v4l2_device(mm_radio_t *radio) +{ + int ret = MM_ERROR_NONE; + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio); + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE_RETURN_VOID(priv_sprd_v4l2); + + /*don't let any other ioctl in other threads*/ + pthread_mutex_lock(&radio->volume_lock); + + /* close radio device here !!!! */ + if (radio->radio_fd >= 0) { + MMRADIO_LOG_INFO("try to close Device"); + ret = close(radio->radio_fd); + if (ret < 0) { + MMRADIO_LOG_ERROR("failed to close radio device[%s] because of %s(%d)\n", + DEFAULT_DEVICE, strerror(errno), errno); + } else { + /* FIXME: if there is sys fs, the device is NOT really closed. */ + + FILE *close_check_file = 0; + int try_cnt = 0; + int status = -1; + +close_check_again: + close_check_file = fopen(FMRX_DEVICE_STATUS, "r"); + if (close_check_file) { + try_cnt++; + fscanf(close_check_file, "%d", &status); + fclose(close_check_file); + close_check_file = NULL; + if (status == 1) { /* device is still opened */ + MMRADIO_LOG_INFO("fmrx_status: %d. device is not closed completely. try again (%d/%d)", status, try_cnt, DEVICE_CLOSE_RETRY_CNT); + if (try_cnt <= DEVICE_CLOSE_RETRY_CNT) { + usleep(100 * 1000); /* FIXME: sleep 100 ms for waiting status changing by FM Radio drv */ + goto close_check_again; + } else { + MMRADIO_LOG_ERROR("timeout: fail to close FM Radio device"); + } + } else if (status == 0) { /* device is closed */ + MMRADIO_LOG_INFO("Device closed successfully"); + } else { /* error case with wrong value */ + MMRADIO_LOG_ERROR("Wrong fmrx_status : %d", status); + } + } else { + MMRADIO_LOG_ERROR("can not open %s (%s:%d)", FMRX_DEVICE_STATUS, strerror(errno), errno); + } + } + radio->radio_fd = -1; + } + + /*remove don't let any other ioctl in other threads*/ + pthread_mutex_unlock(&radio->volume_lock); + + MMRADIO_LOG_FLEAVE(); +} + +int _mmradio_realize(mm_radio_t *radio) +{ + int ret = MM_ERROR_NONE; + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + MMRadioRegionType region = MM_RADIO_REGION_GROUP_EUROPE; + bool update = MM_RADIO_TRUE; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_REALIZE); + + /* we will set recording 5-11 */ + radio->radio_tuning.recording_volume_lower_thres = RECORDING_VOLUME_LOWER_THRESHOLD; + radio->radio_tuning.recording_volume_heigher_thres = RECORDING_VOLUME_HEIGHER_THRESHOLD; + + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE(priv_sprd_v4l2); + + ret = pthread_mutex_init(&radio->volume_lock, NULL); + + /* add volume changed call back */ + MMRADIO_LOG_DEBUG("add mm_sound_add_volume_changed_callback"); + + mm_sound_add_volume_changed_callback(__mmradio_volume_change_cb, (void *)radio); + /* FIXME: for checking device is changed. This can be removed with another solution from sound-server */ + /* add active deviced changed callback */ + MMRADIO_LOG_DEBUG("add mm_sound_add_active_device_changed_callback"); + mm_sound_add_active_device_changed_callback(MM_RADIO_NAME, __mmradio_active_device_changed_cb, (void *)radio); + + /*we have to load the volume tables in libmmradio only for broadcom?? + */ + int number_of_steps = 0; + int index = 0; + int *table = NULL; + + _mm_radio_load_volume_table(&table, &number_of_steps); + if (table) { + MMRADIO_LOG_DEBUG("number of steps -> %d", number_of_steps); + /*copy from temp structure to main strcture*/ + for (index = 0; index < number_of_steps; index++) { + fm_volume_tbl[index] = table[index]; + } + free(table); + table = NULL; + } + + /*TODO: double check*/ + priv_sprd_v4l2->device_ready = MM_RADIO_FALSE; + + + /*seek cancel*/ + ret = pthread_mutex_init(&radio->state_mutex, NULL); + if (ret < 0) { + MMRADIO_LOG_DEBUG("Mutex creation failed %d", ret); + } + + /*seek cancel*/ + ret = pthread_mutex_init(&priv_sprd_v4l2->seek_cancel_mutex, NULL); + if (ret < 0) { + MMRADIO_LOG_DEBUG("Mutex creation failed %d", ret); + } + + MMRADIO_LOG_ERROR("_mmradio_realize_pipeline radio->region_setting.country : %d\n", radio->region_setting.country); + /*Init Region settings*/ + /* 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 = MM_RADIO_TRUE; + } else {/* already initialized by application */ + region = radio->region_setting.country; + } + ret = _mmradio_apply_region(radio, region, update); + MMRADIO_CHECK_RETURN_IF_FAIL(ret, "set apply region"); +#ifdef USE_GST_PIPELINE + ret = _mmradio_realize_pipeline(radio); + if (ret) { + MMRADIO_LOG_ERROR("_mmradio_realize_pipeline is failed\n"); + return ret; + } +#endif + radio->is_muted = MM_RADIO_FALSE; + + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY); + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_NONE; +} + +int _mmradio_unrealize(mm_radio_t *radio) +{ + int ret = MM_ERROR_NONE; + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_UNREALIZE); + + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE(priv_sprd_v4l2); + + /*Finish if there are scans*/ + _mmradio_stop_scan(radio); + /*Stop radio if started*/ + _mmradio_stop(radio); + + + /*If applicaiton hasn't called unpreapre let us prepare*/ + _mmradio_unprepare_device(radio); + MMRADIO_LOG_INFO("device Unprep done"); + + mm_sound_remove_volume_changed_callback(); + mm_sound_remove_active_device_changed_callback(MM_RADIO_NAME); + + pthread_mutex_destroy(&radio->volume_lock); + pthread_mutex_destroy(&priv_sprd_v4l2->seek_cancel_mutex); + pthread_mutex_destroy(&radio->state_mutex); + + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_NULL); +#ifndef FEATURE_ASM_SUPPORT + ret = mmradio_set_audio_focus(&radio->sm, _mmradio_sound_focus_watch_cb, FALSE, (void *)radio); +#endif +#ifdef USE_GST_PIPELINE + ret = _mmradio_destroy_pipeline(radio); + if (ret) { + MMRADIO_LOG_ERROR("_mmradio_destroy_pipeline is failed\n"); + return ret; + } +#endif + MMRADIO_LOG_FLEAVE(); + return ret; +} + +int _mmradio_destroy(mm_radio_t *radio) +{ + int ret = MM_ERROR_NONE; + mm_radio_priv_v4l2_t *priv_v4l2_handle = NULL; + + MMRADIO_LOG_INFO(""); + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_DESTROY); + + _mmradio_unrealize(radio); + +#ifdef FEATURE_ASM_SUPPORT + ret = mmradio_asm_deregister(&radio->sm); +#else + ret = mmradio_audio_focus_deregister(&radio->sm); +#endif + if (ret) { + MMRADIO_LOG_ERROR("failed to deregister asm server\n"); + return MM_ERROR_RADIO_INTERNAL; + } + + priv_v4l2_handle = (mm_radio_priv_v4l2_t *)radio->vender_specific_handle; + if (priv_v4l2_handle) { + free(priv_v4l2_handle); + radio->vender_specific_handle = NULL; + } + _mm_radio_event_s *event = g_slice_new0(_mm_radio_event_s); + + if (event == NULL) + return MM_ERROR_RADIO_INTERNAL; + + event->event_type = MMRADIO_EVENT_DESTROY; + + g_async_queue_push_sorted(radio->event_queue, event, event_comparator, NULL); + pthread_join(radio->event_thread, NULL); + + /*Clean up frequency related variables*/ + g_async_queue_unref(radio->event_queue); + + MMRADIO_LOG_INFO(""); + + return ret; +} + +void __mmradio_event_thread(mm_radio_t *radio) +{ + int ret = MM_ERROR_NONE; + MMMessageParamType param = {0,}; + _mm_radio_event_s *event = NULL; + int exit_event_thread = 0; + + /*we run a while one loop*/ + while (exit_event_thread == 0) { + event = (_mm_radio_event_s *)g_async_queue_pop(radio->event_queue); + if (event == NULL) { + MMRADIO_LOG_ERROR("poped message is NULL!"); + goto exit; + } + + /*Its okay to use the command because they are nicely sorted for our needs + * also frequency is way above the needs of our commands simple and less complicated*/ + switch (event->event_type) { + case MMRADIO_EVENT_DESTROY: + MMRADIO_LOG_INFO("get destroy event. pop all event to finish this thread"); + while ((event = (_mm_radio_event_s *)g_async_queue_try_pop(radio->event_queue))) { + if (event != NULL) { + MMRADIO_LOG_DEBUG("drop this msg type: %d", event->event_type); + g_slice_free(_mm_radio_event_s, event); + } + } + exit_event_thread = 1; + break; + + case MMRADIO_EVENT_STOP: + MMRADIO_LOG_INFO("async close device is requested"); + /*we don't clear the frequency here, this might create a problem + * setting frequency after stop??*/ + pthread_mutex_lock(&radio->state_mutex); + __mmradio_deinit_v4l2_device(radio); + pthread_mutex_unlock(&radio->state_mutex); + _mmradio_unprepare_device(radio); + break; + + case MMRADIO_EVENT_SET_FREQ_ASYNC: + MMRADIO_LOG_INFO("processing frequency: %d", event->event_data); + /*we try to call mm_radio api here this is done on purpose, to make sure that cmd lock is held*/ + ret = mm_radio_set_frequency(radio, event->event_data); + if (ret == MM_ERROR_NONE) { + param.radio_scan.frequency = event->event_data; + } else { + param.radio_scan.frequency = ret; /* FIMXE: we need this? */ + } + MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SET_FREQUENCY, ¶m); + break; + + default: + MMRADIO_LOG_ERROR("wrong event_type: %d", event->event_data); + break; + } + } + +exit: + if (event) { + g_slice_free(_mm_radio_event_s, event); + } + MMRADIO_LOG_INFO("event thread is finished"); +} + +int _mmradio_set_frequency_async(mm_radio_t *radio, int freq) +{ + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_FREQ); + + /* check frequency range */ + if (freq < radio->region_setting.band_min + || freq > radio->region_setting.band_max) { + MMRADIO_LOG_ERROR("out of frequency range - %d\n", freq); + return MM_ERROR_INVALID_ARGUMENT; + } + + _mm_radio_event_s *event = g_slice_new0(_mm_radio_event_s); + + if (event == NULL) + return MM_ERROR_RADIO_INTERNAL; + + event->event_type = MMRADIO_EVENT_SET_FREQ_ASYNC; + event->event_data = freq; + + g_async_queue_push(radio->event_queue, event); + + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_NONE; +} + +int _mmradio_set_frequency(mm_radio_t *radio, int freq) /* unit should be KHz */ +{ + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + int ret = 0; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_FREQ); + + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE(priv_sprd_v4l2); + + /* check frequency range */ + if (freq < radio->region_setting.band_min + || freq > radio->region_setting.band_max) { + MMRADIO_LOG_ERROR("out of frequency range - %d\n", freq); + return MM_ERROR_INVALID_ARGUMENT; + } + + if (radio->radio_fd < 0) { + radio->freq = freq; + MMRADIO_LOG_WARNING("radio device is not opened to set (%d)! retun ok.", freq); + return MM_ERROR_NONE; + } else { + + /* set it */ + (priv_sprd_v4l2->vf).tuner = 0; + (priv_sprd_v4l2->vf).type = V4L2_TUNER_RADIO; /* if we do not set type, we will get EINVAL */ + (priv_sprd_v4l2->vf).frequency = RADIO_FREQ_FORMAT_SET(freq); + + MMRADIO_LOG_DEBUG("Setting %d frequency\n", freq); + + ret = ioctl(radio->radio_fd, VIDIOC_S_FREQUENCY, &(priv_sprd_v4l2->vf)) ; + if (ret < 0) { + MMRADIO_LOG_ERROR("VIDIOC_S_FREQUENCY failed with %s", strerror(errno)); + return MM_ERROR_RADIO_INTERNAL; + } + } + /*Only update if the ioctl was successful*/ + radio->freq = freq; + + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_NONE; +} + +int _mmradio_get_frequency(mm_radio_t *radio, int *pFreq) +{ + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_FREQ); + + return_val_if_fail(pFreq, MM_ERROR_INVALID_ARGUMENT); + + /* update freq from handle */ + *pFreq = radio->freq; + + MMRADIO_LOG_DEBUG("Getting %d frequency\n", radio->freq); + + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_NONE; +} + +static void _mmradio_fadevolume_cancel(mm_radio_t *radio) +{ + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + + MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio); + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE_RETURN_VOID(priv_sprd_v4l2); + if (priv_sprd_v4l2->volume_fade.fade_volume_thread) { + pthread_cancel(priv_sprd_v4l2->volume_fade.fade_volume_thread); + pthread_join(priv_sprd_v4l2->volume_fade.fade_volume_thread, NULL); + priv_sprd_v4l2->volume_fade.fade_volume_thread = 0; + } +} + + +static void __mmradio_fade_volume_thread(mm_radio_t *radio) +{ + int ret = 0; + int index = 0; + + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio); + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE_RETURN_VOID(priv_sprd_v4l2); + + if (priv_sprd_v4l2->volume_fade.initial_volume < priv_sprd_v4l2->volume_fade.final_volume) { + /*increasing index*/ + do { + usleep(100 * 1000); + priv_sprd_v4l2->volume_fade.initial_volume++; + ret = __mmradio_set_volume(radio, priv_sprd_v4l2->volume_fade.initial_volume); + if (ret != 0) { + /*When this happens usually state is changed*/ + priv_sprd_v4l2->volume_fade.fade_finished = MM_RADIO_TRUE; + MMRADIO_LOG_ERROR("set volume failed so no more fading for this request"); + return; + } + } while (priv_sprd_v4l2->volume_fade.initial_volume != priv_sprd_v4l2->volume_fade.final_volume); + } else { + /*decreasing index*/ + do { + usleep(100 * 1000); + priv_sprd_v4l2->volume_fade.initial_volume--; + ret = __mmradio_set_volume(radio, priv_sprd_v4l2->volume_fade.initial_volume); + if (ret != 0) { + /*When this happens usually state is changed*/ + priv_sprd_v4l2->volume_fade.fade_finished = MM_RADIO_TRUE; + MMRADIO_LOG_ERROR("set volume failed so no more fading for this request"); + return; + } + } while (priv_sprd_v4l2->volume_fade.initial_volume != priv_sprd_v4l2->volume_fade.final_volume); + } + priv_sprd_v4l2->volume_fade.fade_finished = MM_RADIO_TRUE; +} + +/* + * Description: This function fades in and out fm volume, + * pseudo: open a thread, change the volume in steps in time intervals + * */ +static void _mmradio_fadevolume(mm_radio_t *radio, int initial_volume, int final_volume) +{ + int ret = 0; + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + + MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio); + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE_RETURN_VOID(priv_sprd_v4l2); + + if (initial_volume == final_volume) { + MMRADIO_LOG_INFO("volume is same no need to fade volume"); + return; + } + + /*cancel any outstanding request*/ + _mmradio_fadevolume_cancel(radio); + + if (priv_sprd_v4l2->volume_fade.fade_finished) { + priv_sprd_v4l2->volume_fade.initial_volume = initial_volume; + } + if (!priv_sprd_v4l2->volume_fade.initial_volume) { + priv_sprd_v4l2->volume_fade.initial_volume = initial_volume; + } + + priv_sprd_v4l2->volume_fade.final_volume = final_volume; + + if (priv_sprd_v4l2->volume_fade.final_volume == priv_sprd_v4l2->volume_fade.initial_volume) { + MMRADIO_LOG_INFO("volume is same no need to fade volume"); + return; + } + + if (radio->current_state != MM_RADIO_STATE_PLAYING) { + MMRADIO_LOG_ERROR("we are not in playing state we are in state %d don't fade volume!!", radio->current_state); + return; + } + + priv_sprd_v4l2->volume_fade.fade_finished = MM_RADIO_FALSE; + MMRADIO_LOG_INFO("fade from %d to %d", priv_sprd_v4l2->volume_fade.initial_volume, priv_sprd_v4l2->volume_fade.final_volume); + + ret = pthread_create(&priv_sprd_v4l2->volume_fade.fade_volume_thread, NULL, + (void *)__mmradio_fade_volume_thread, (void *)radio); + if (ret < 0) { + MMRADIO_LOG_ERROR("fade volume thread creation failed - %d", ret); + return ; + } +} + +static int _mm_radio_recording_volume_change_policy(mm_radio_t *radio, int present_volume) +{ + /* If lower than lower threshold return lower threshold */ + if (present_volume < radio->radio_tuning.recording_volume_lower_thres) { + return radio->radio_tuning.recording_volume_lower_thres; + } + if (present_volume > radio->radio_tuning.recording_volume_heigher_thres) { + return radio->radio_tuning.recording_volume_heigher_thres; + } + return present_volume; +} + +static void __mmradio_volume_change_cb(volume_type_t type, unsigned int volume, void *user_data) +{ + mm_radio_t *radio = (mm_radio_t *)user_data; + + if (type == VOLUME_TYPE_MEDIA) { + MMRADIO_LOG_DEBUG("Change FM Radio volume to %d\n", volume); + __mmradio_set_volume(radio, volume); + } +} + +/* FIXME: for checking device is changed. This can be removed with another solution from sound-server */ +static void __mmradio_active_device_changed_cb(mm_sound_device_in device_in, mm_sound_device_out device_out, void *user_data) +{ + mm_radio_t *radio = (mm_radio_t *)user_data; + unsigned int volume = 0; + unsigned int recording_volume = 0; + + MMRADIO_LOG_DEBUG("active_device_changed: in[0x%08x], out[0x%08x]\n", device_in, device_out); + + /* normal case */ + mm_sound_volume_get_value(VOLUME_TYPE_MEDIA, &volume); + + MMRADIO_LOG_DEBUG("Change FM Radio volume to %d\n", volume); + __mmradio_set_volume(radio, volume); +} + +static int __mmradio_set_volume(mm_radio_t *radio, unsigned int value) +{ + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_VOLUME); + + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE(priv_sprd_v4l2); + + if (radio->radio_fd < 0) { + return MM_ERROR_RADIO_NOT_INITIALIZED; + } + + /*During scanning or seeing it is not advisable to control volume + * refer to PLM - P141022-00376*/ + if (radio->is_seeking || radio->current_state == MM_RADIO_STATE_SCANNING) { + MMRADIO_LOG_INFO("We are either seeking or scanning best not to set volume"); + return MM_ERROR_NONE; + } + + pthread_mutex_lock(&radio->volume_lock); + + if (radio->radio_fd > 0) { + (priv_sprd_v4l2->vctrl).id = V4L2_CID_AUDIO_VOLUME; + (priv_sprd_v4l2->vctrl).value = fm_volume_tbl[value]; + + MMRADIO_LOG_INFO("set volume:%d", (priv_sprd_v4l2->vctrl).value); + + if (ioctl(radio->radio_fd, VIDIOC_S_CTRL, &(priv_sprd_v4l2->vctrl)) < 0) { + MMRADIO_LOG_ERROR("failed to set volume %s\n", strerror(errno)); + pthread_mutex_unlock(&radio->volume_lock); + return MM_ERROR_RADIO_INTERNAL; + } + } else { + MMRADIO_LOG_WARNING("radio_fd (%d) is closed already.", radio->radio_fd); + } + + pthread_mutex_unlock(&radio->volume_lock); + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; +} + +static int __mmradio_get_volume(mm_radio_t *radio, unsigned int *value) +{ + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_VOLUME); + + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE(priv_sprd_v4l2); + + if (radio->radio_fd < 0) { + return MM_ERROR_RADIO_NOT_INITIALIZED; + } + + pthread_mutex_lock(&radio->volume_lock); + + if (radio->radio_fd > 0) { + (priv_sprd_v4l2->vctrl).id = V4L2_CID_AUDIO_VOLUME; + + if (ioctl(radio->radio_fd, VIDIOC_G_CTRL, &(priv_sprd_v4l2->vctrl)) < 0) { + *value = 0; + MMRADIO_LOG_ERROR("failed to get volume - %s\n", strerror(errno)); + pthread_mutex_unlock(&radio->volume_lock); + return MM_ERROR_RADIO_INTERNAL; + } + *value = (((priv_sprd_v4l2->vctrl).value - FM_VOLUME_BASE) / (FM_VOLUME_MAX - 1)); + } else { + MMRADIO_LOG_WARNING("radio_fd (%d) is closed already.", radio->radio_fd); + } + + pthread_mutex_unlock(&radio->volume_lock); + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; +} + +int _mmradio_mute(mm_radio_t *radio) +{ + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + + MMRADIO_LOG_INFO(""); + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_MUTE); + + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE(priv_sprd_v4l2); + + if (radio->radio_fd < 0) { + radio->is_muted = MM_RADIO_TRUE; + MMRADIO_LOG_WARNING("radio_fd (%d) is not opened", radio->radio_fd); + return MM_ERROR_NONE; + } + + /*Why mute if already muted*/ + if (radio->is_muted) { + MMRADIO_LOG_WARNING("Already Muted why mute again"); + return MM_ERROR_NONE; + } + + pthread_mutex_lock(&radio->volume_lock); + + if (radio->radio_fd > 0) { + (priv_sprd_v4l2->vctrl).id = V4L2_CID_AUDIO_MUTE; + (priv_sprd_v4l2->vctrl).value = 1; /* mute */ + + if (ioctl(radio->radio_fd, VIDIOC_S_CTRL, &(priv_sprd_v4l2->vctrl)) < 0) { + MMRADIO_LOG_ERROR(" failed VIDIOC_S_CTRL- %s\n", strerror(errno)); + pthread_mutex_unlock(&radio->volume_lock); + return MM_ERROR_RADIO_NOT_INITIALIZED; + } + } + radio->is_muted = MM_RADIO_TRUE; + + pthread_mutex_unlock(&radio->volume_lock); + + MMRADIO_LOG_INFO(""); + + return MM_ERROR_NONE; + +} + +int _mmradio_unmute(mm_radio_t *radio) +{ + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + + MMRADIO_LOG_INFO(""); + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_UNMUTE); + MMRADIO_CHECK_DEVICE_STATE(radio); + + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE(priv_sprd_v4l2); + + if (radio->radio_fd < 0) { + radio->is_muted = MM_RADIO_FALSE; + MMRADIO_LOG_WARNING("radio_fd (%d) is not opened", radio->radio_fd); + return MM_ERROR_NONE; + } + + /*Why ummute if already ummuted*/ + if (!radio->is_muted) { + MMRADIO_LOG_WARNING("Already Unmuted why unmute again"); + return MM_ERROR_NONE; + } + + pthread_mutex_lock(&radio->volume_lock); + + if (radio->radio_fd > 0) { + (priv_sprd_v4l2->vctrl).id = V4L2_CID_AUDIO_MUTE; + (priv_sprd_v4l2->vctrl).value = 0; /* unmute */ + + if (ioctl(radio->radio_fd, VIDIOC_S_CTRL, &(priv_sprd_v4l2->vctrl)) < 0) { + MMRADIO_LOG_ERROR(" failed VIDIOC_S_CTRL- %s\n", strerror(errno)); + + pthread_mutex_unlock(&radio->volume_lock); + + return MM_ERROR_RADIO_NOT_INITIALIZED; + } + } + radio->is_muted = MM_RADIO_FALSE; + + pthread_mutex_unlock(&radio->volume_lock); + + MMRADIO_LOG_INFO(""); + + return MM_ERROR_NONE; +} + +int __mmradio_mute_internal(mm_radio_t *radio) +{ + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + MMRADIO_LOG_INFO(""); + + MMRADIO_CHECK_INSTANCE(radio); + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE(priv_sprd_v4l2); + + if (radio->radio_fd < 0) { + MMRADIO_LOG_WARNING("radio_fd (%d) is not opened", radio->radio_fd); + return MM_ERROR_NONE; + } + + pthread_mutex_lock(&radio->volume_lock); + + if (radio->radio_fd > 0) { + (priv_sprd_v4l2->vctrl).id = V4L2_CID_AUDIO_MUTE; + (priv_sprd_v4l2->vctrl).value = 1; /* mute */ + + if (ioctl(radio->radio_fd, VIDIOC_S_CTRL, &(priv_sprd_v4l2->vctrl)) < 0) { + MMRADIO_LOG_ERROR(" failed VIDIOC_S_CTRL- %s\n", strerror(errno)); + pthread_mutex_unlock(&radio->volume_lock); + return MM_ERROR_RADIO_NOT_INITIALIZED; + } + } + + pthread_mutex_unlock(&radio->volume_lock); + + MMRADIO_LOG_INFO(""); + return MM_ERROR_NONE; + +} + +int __mmradio_unmute_internal(mm_radio_t *radio) +{ + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + MMRADIO_LOG_INFO(""); + + MMRADIO_CHECK_INSTANCE(radio); + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE(priv_sprd_v4l2); + + if (radio->radio_fd < 0) { + MMRADIO_LOG_WARNING("radio_fd (%d) is not opened", radio->radio_fd); + return MM_ERROR_NONE; + } + + pthread_mutex_lock(&radio->volume_lock); + + if (radio->radio_fd > 0) { + (priv_sprd_v4l2->vctrl).id = V4L2_CID_AUDIO_MUTE; + (priv_sprd_v4l2->vctrl).value = 0; /* unmute */ + + if (ioctl(radio->radio_fd, VIDIOC_S_CTRL, &(priv_sprd_v4l2->vctrl)) < 0) { + MMRADIO_LOG_ERROR(" failed VIDIOC_S_CTRL- %s\n", strerror(errno)); + pthread_mutex_unlock(&radio->volume_lock); + return MM_ERROR_RADIO_NOT_INITIALIZED; + } + } + + pthread_mutex_unlock(&radio->volume_lock); + + MMRADIO_LOG_INFO(""); + return MM_ERROR_NONE; +} + + +/* -------------------------------------------------------------------------- + * Name : __mmradio_set_band_range + * Desc : apply max and min frequency to device_mmradio_stop + * Param : + * [in] radio : radio handle + * Return : zero on success, or negative value with error code + *---------------------------------------------------------------------------*/ +static int __mmradio_set_band_range(mm_radio_t *radio) +{ + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE(priv_sprd_v4l2); + + /* get min and max freq. */ + (priv_sprd_v4l2->vt).rangelow = RADIO_FREQ_FORMAT_SET(radio->region_setting.band_min); + (priv_sprd_v4l2->vt).rangehigh = RADIO_FREQ_FORMAT_SET(radio->region_setting.band_max); + + + if (radio->radio_fd < 0) { + MMRADIO_LOG_DEBUG("Device not ready so sending 0\n"); + return MM_ERROR_RADIO_INTERNAL; + } else { + /* set it to device */ + if (ioctl(radio->radio_fd, VIDIOC_S_TUNER, &(priv_sprd_v4l2->vt)) < 0) { + MMRADIO_LOG_ERROR("failed to set band range - %s\n", strerror(errno)); + return MM_ERROR_RADIO_INTERNAL; + } + } + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; +} + +int _mmradio_set_message_callback(mm_radio_t *radio, MMMessageCallback callback, void *user_param) +{ + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + + radio->msg_cb = callback; + radio->msg_cb_param = user_param; + + MMRADIO_LOG_DEBUG("msg_cb : 0x%x msg_cb_param : 0x%x\n", (unsigned int)callback, (unsigned int)user_param); + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; +} + +int _mmradio_get_state(mm_radio_t *radio, int *pState) +{ + int state = 0; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + return_val_if_fail(pState, MM_ERROR_INVALID_ARGUMENT); + + state = __mmradio_get_state(radio); + + *pState = state; + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; +} + +int _mmradio_start(mm_radio_t *radio) +{ + int ret = MM_ERROR_NONE; + bool is_connected = false; + unsigned int volume = 0; + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_START); + + pthread_mutex_lock(&radio->state_mutex); + MMRADIO_LOG_INFO(""); + ret = _mmradio_prepare_device(radio); + if (ret) { + MMRADIO_LOG_ERROR("Coundn't prepare the device - 0x%x\n", ret); + goto error; + } + ret = __mmradio_init_v4l2_device(radio); + if (ret) { + MMRADIO_LOG_ERROR("Coundn't init the device - 0x%x\n", ret); + goto error; + } + + mm_sound_volume_get_value(VOLUME_TYPE_MEDIA, &volume); + __mmradio_set_volume(radio, volume); + + /* set stored frequency */ + _mmradio_set_frequency(radio, radio->freq); + /*apply Tuning Parameters*/ + + usleep(100 * 1000); /* FIXME: reduce FM Radio turn on noise */ + +#ifdef MM_RADIO_EAR_PHONE_POLICY + ret = _mmradio_get_device_available(radio, &is_connected); + if (!is_connected) { + MMRADIO_LOG_ERROR("SOUND_DEVICE_AUDIO_JACK is not connected, radio can't play without audio jack"); + ret = MM_ERROR_RADIO_NO_ANTENNA; + goto error; + } +#endif + + +#ifdef FEATURE_ASM_SUPPORT + radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE; /*add this so asm state is always updated*/ + ret = mmradio_asm_set_state(&radio->sm, ASM_STATE_PLAYING, ASM_RESOURCE_RADIO_TUNNER); +#else + ret = mmradio_set_audio_focus(&radio->sm, _mmradio_sound_focus_watch_cb, TRUE, (void *)radio); +#endif + if (ret) { + MMRADIO_LOG_ERROR("failed to set asm state to PLAYING\n"); + goto error; + } + +#ifdef MM_RADIO_EAR_PHONE_POLICY + ret = _mmradio_get_device_available(radio, &is_connected); + if (!is_connected) { + MMRADIO_LOG_ERROR("SOUND_DEVICE_AUDIO_JACK is not connected, radio can't play without audio jack"); + ret = MM_ERROR_RADIO_NO_ANTENNA; + goto error; + } +#endif + + /* unmute : mute is not called but broadcom start as muted. we will unmute at here */ + if (radio->is_muted == MM_RADIO_FALSE) { + MMRADIO_LOG_INFO("unmute in start sequence"); + if (__mmradio_unmute_internal(radio) != MM_ERROR_NONE) { + MMRADIO_LOG_ERROR("set unmute_internal is failed\n"); + } + } + + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_PLAYING); + +#ifdef USE_GST_PIPELINE + ret = _mmradio_start_pipeline(radio); + if (ret) { + MMRADIO_LOG_ERROR("_mmradio_start_pipeline is failed\n"); + goto error; + } +#endif + MMRADIO_LOG_INFO(""); + pthread_mutex_unlock(&radio->state_mutex); + return ret; + +error: +#ifdef FEATURE_ASM_SUPPORT + if (radio->sm.state == ASM_STATE_PLAYING) { + if (mmradio_asm_set_state(&radio->sm, ASM_STATE_STOP, ASM_RESOURCE_NONE)) { + MMRADIO_LOG_ERROR("failed to set asm-state to stop"); + } + } +#endif + __mmradio_deinit_v4l2_device(radio); + + pthread_mutex_unlock(&radio->state_mutex); + _mmradio_unprepare_device(radio); + MMRADIO_LOG_ERROR(" with ret = 0x%x", ret); + return ret; +} + +int _mmradio_stop(mm_radio_t *radio) +{ + int ret = MM_ERROR_NONE; + + MMRADIO_CHECK_INSTANCE(radio); + /*MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_STOP); */ + pthread_mutex_lock(&radio->state_mutex); + + MMRADIO_CHECK_STATE_GOTO_IF_FAIL(ret, radio, MMRADIO_COMMAND_STOP, error); + MMRADIO_LOG_INFO(""); + + + radio->seek_unmute = MM_RADIO_FALSE; + /*cancel if any seek*/ + _mmradio_seek_cancel(radio); + /*If there is volume fading going on we better stop it*/ + _mmradio_fadevolume_cancel(radio); + + /* mute for stop */ + MMRADIO_LOG_INFO("mute in stop sequence"); + if (__mmradio_mute_internal(radio) != MM_ERROR_NONE) { + MMRADIO_LOG_ERROR("set mute_internal is failed\n"); + } + + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY); +#ifdef FEATURE_ASM_SUPPORT + ret = mmradio_asm_set_state(&radio->sm, ASM_STATE_STOP, ASM_RESOURCE_NONE); + if (ret) { + MMRADIO_LOG_ERROR("failed to set asm state to STOPEED\n"); + goto error; + } +#endif +#ifdef USE_GST_PIPELINE + ret = _mmradio_stop_pipeline(radio); + if (ret) { + MMRADIO_LOG_ERROR("_mmradio_stop_pipeline is failed\n"); + goto error; + } +#endif + + /*call by application*/ + if (radio->sm.by_asm_cb == MMRADIO_ASM_CB_NONE) { + __mmradio_deinit_v4l2_device(radio); + } + MMRADIO_LOG_INFO("Radio Stopped"); + + + MMRADIO_LOG_INFO(""); + pthread_mutex_unlock(&radio->state_mutex); + return ret; +error: + MMRADIO_LOG_ERROR(" with ret = 0x%x", ret); + pthread_mutex_unlock(&radio->state_mutex); + return ret; +} + +/* There is no concept of pause in radio transmission. + * This is essentially a stop call, + * but this is added to keep sound-server's state in order */ +int _mmradio_pause(mm_radio_t *radio) +{ + int ret = MM_ERROR_NONE; + + MMRADIO_CHECK_INSTANCE(radio); + + pthread_mutex_lock(&radio->state_mutex); + MMRADIO_CHECK_STATE_GOTO_IF_FAIL(ret, radio, MMRADIO_COMMAND_STOP, error); + MMRADIO_LOG_INFO(""); + + radio->seek_unmute = MM_RADIO_FALSE; + /*cancel if any seek*/ + _mmradio_seek_cancel(radio); + /*If there is volume fading going on we better stop it*/ + _mmradio_fadevolume_cancel(radio); + + /* mute for pause */ + MMRADIO_LOG_INFO("mute in pause sequence"); + if (__mmradio_mute_internal(radio) != MM_ERROR_NONE) { + MMRADIO_LOG_ERROR("set mute_internal is failed\n"); + } + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY); +#ifdef FEATURE_ASM_SUPPORT + ret = mmradio_asm_set_state(&radio->sm, ASM_STATE_PAUSE, ASM_RESOURCE_NONE); + if (ret) { + MMRADIO_LOG_ERROR("failed to set asm state to PLAYING\n"); + goto error; + } +#endif +#ifdef USE_GST_PIPELINE + ret = _mmradio_stop_pipeline(radio); + if (ret) { + MMRADIO_LOG_ERROR("_mmradio_stop_pipeline is failed\n"); + goto error; + } +#endif + + if (radio->sm.by_asm_cb == MMRADIO_ASM_CB_NONE) { + __mmradio_deinit_v4l2_device(radio); + } + MMRADIO_LOG_INFO("Radio Stopped from pause"); + MMRADIO_LOG_INFO(""); + pthread_mutex_unlock(&radio->state_mutex); + return ret; +error: + MMRADIO_LOG_ERROR(" with ret = 0x%x", ret); + pthread_mutex_unlock(&radio->state_mutex); + return ret; +} + +int _mmradio_seek(mm_radio_t *radio, MMRadioSeekDirectionType direction) +{ + int ret = 0; + + MMRADIO_LOG_INFO(""); + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SEEK); + + 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; + } + + radio->seek_unmute = MM_RADIO_FALSE; + radio->is_seeking = MM_RADIO_TRUE; + radio->seek_cancel = MM_RADIO_FALSE; + if (!radio->is_muted) { + if (_mmradio_mute(radio) != MM_ERROR_NONE) { + return MM_ERROR_RADIO_NOT_INITIALIZED; + } + radio->seek_unmute = MM_RADIO_TRUE; + } + + MMRADIO_LOG_DEBUG("trying to seek. direction[0:UP/1:DOWN) %d\n", direction); + radio->seek_direction = direction; + + ret = pthread_create(&radio->seek_thread, NULL, + (void *)__mmradio_seek_thread, (void *)radio); + + if (ret) { + MMRADIO_LOG_DEBUG("failed create thread\n"); + /*reset parameters*/ + radio->is_seeking = MM_RADIO_FALSE; + radio->seek_cancel = MM_RADIO_TRUE; + if (radio->seek_unmute) { + if (_mmradio_unmute(radio) != MM_ERROR_NONE) { + radio->seek_unmute = MM_RADIO_FALSE; + } + } + return MM_ERROR_RADIO_INTERNAL; + } + MMRADIO_LOG_INFO(""); + + return MM_ERROR_NONE; +} + +void _mmradio_seek_cancel(mm_radio_t *radio) +{ + int ret = 0; + MMRADIO_LOG_INFO(""); + + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + /*cancel any outstanding seek request*/ + radio->seek_cancel = MM_RADIO_TRUE; + if (radio->seek_thread) { + ret = pthread_mutex_trylock(&priv_sprd_v4l2->seek_cancel_mutex); + MMRADIO_LOG_DEBUG("try lock ret: %s (%d)", strerror(ret), 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(&priv_sprd_v4l2->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 = MM_RADIO_FALSE; + radio->seek_thread = 0; + } + MMRADIO_LOG_INFO(""); +} + +int _mmradio_start_scan(mm_radio_t *radio) +{ + int ret = MM_ERROR_NONE; + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_START_SCAN); + + int scan_tr_id = 0; + + pthread_mutex_lock(&radio->state_mutex); + MMRADIO_LOG_INFO(""); + + /*Lets hope that device is prepared already if not no matter we'll try to prepare*/ + MMRADIO_LOG_INFO("Starting Radio in Scan"); + ret = _mmradio_prepare_device(radio); + if (ret) { + MMRADIO_LOG_ERROR("Coundn't prepare the device - 0x%x\n", ret); + goto error; + } + ret = __mmradio_init_v4l2_device(radio); + if (ret) { + MMRADIO_LOG_ERROR("Coundn't init the device - 0x%x\n", ret); + goto error; + } + + radio->stop_scan = MM_RADIO_FALSE; + + scan_tr_id = pthread_create(&radio->scan_thread, NULL, + (void *)__mmradio_scan_thread, (void *)radio); + + if (scan_tr_id != 0) { + MMRADIO_LOG_DEBUG("failed to create thread : scan\n"); + ret = MM_ERROR_RADIO_NOT_INITIALIZED; + goto error; + } + + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_SCANNING); + + MMRADIO_LOG_INFO(""); + pthread_mutex_unlock(&radio->state_mutex); + return MM_ERROR_NONE; +error: + MMRADIO_LOG_ERROR(" with ret = 0x%x", ret); + pthread_mutex_unlock(&radio->state_mutex); + return ret; +} + +int _mmradio_stop_scan(mm_radio_t *radio) +{ + MMRADIO_LOG_INFO(""); + int ret = 0; + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_STOP_SCAN); + + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE(priv_sprd_v4l2); + + radio->stop_scan = MM_RADIO_TRUE; + + if (radio->scan_thread) { + /* make sure all the search is stopped else we'll wait till search finish which is not ideal*/ + ret = pthread_mutex_trylock(&priv_sprd_v4l2->seek_cancel_mutex); + MMRADIO_LOG_DEBUG("try lock ret: %s (%d)", strerror(ret), 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(&priv_sprd_v4l2->seek_cancel_mutex); + } else { + MMRADIO_LOG_ERROR("trylock is failed but Not EBUSY. ret: %d", ret); + } + MMRADIO_LOG_DEBUG("pthread_join scan_thread"); + pthread_join(radio->scan_thread, NULL); + /*Clean up radio*/ + __mmradio_deinit_v4l2_device(radio); + radio->scan_thread = 0; + } + + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY); + + /*if there were any volume changes, we better set them right here + * refer to PLM - P141022-00376*/ + { + int volume = 0; + ret = mm_sound_volume_get_value(VOLUME_TYPE_MEDIA, &volume); + if (ret) { + MMRADIO_LOG_ERROR("mm_sound_volume_get_value failed with [0x%x]", ret); + } else { + /*we are good to set volume here*/ + ret = __mmradio_set_volume(radio, volume); + if (ret) { + MMRADIO_LOG_ERROR("__mmradio_set_volume failed with [0x%x]", ret); + } + } + } + + MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_STOP, NULL); + + MMRADIO_LOG_INFO(""); + + return MM_ERROR_NONE; +} + +int _mm_radio_get_signal_strength(mm_radio_t *radio, int *value) +{ + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + return_val_if_fail(value, MM_ERROR_INVALID_ARGUMENT); + + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE(priv_sprd_v4l2); + + /* 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"); + *value = 0; + return MM_ERROR_NONE; + } else { + if (ioctl(radio->radio_fd, VIDIOC_G_TUNER, &(priv_sprd_v4l2->vt)) < 0) { + MMRADIO_LOG_ERROR("ioctl VIDIOC_G_TUNER error - %s\n", strerror(errno)); + return MM_ERROR_RADIO_INTERNAL; + } + } + + /* RSSI from controller will be in range of -128 to +127. + But V4L2 API defines the range of 0 to 65535. So convert this value + FM rssi is cannot be 1~128 dbm normally, although range is -128 to +127 */ + /* (65535 / 128) = 511.9921875. kernel will also use same value */ + *value = priv_sprd_v4l2->vt.signal / 511 /*(65535/128)*/ - 128; + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_NONE; +} + +static void __mmradio_scan_thread(mm_radio_t *radio) +{ + int ret = 0; + int prev_freq = 0; + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + 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); + + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *)radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE_RETURN_VOID(priv_sprd_v4l2); + + MMRADIO_LOG_INFO("mute in scan thread"); + if (__mmradio_mute_internal(radio) != MM_ERROR_NONE) { + MMRADIO_LOG_ERROR("set mute_internal is failed\n"); + }; + + if (_mmradio_set_frequency(radio, radio->region_setting.band_min) != MM_ERROR_NONE) { + MMRADIO_LOG_ERROR("set min freq failed during scanning. min freq: %d", radio->region_setting.band_min); + goto FINISHED; + } else { + MMRADIO_LOG_DEBUG("scan start with min freq: %d", radio->region_setting.band_min); + } + + 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; + MMMessageParamType param = {0,}; + + MMRADIO_LOG_DEBUG("try to scan"); + pthread_mutex_lock(&priv_sprd_v4l2->seek_cancel_mutex); + MMRADIO_LOG_DEBUG("search start during scanning\n"); + if (radio->stop_scan) { + MMRADIO_LOG_DEBUG("scan was canceled why search so we return"); + pthread_mutex_unlock(&priv_sprd_v4l2->seek_cancel_mutex); + goto FINISHED; + } + ret = ioctl(radio->radio_fd, VIDIOC_S_HW_FREQ_SEEK, &vs); + MMRADIO_LOG_DEBUG("search end during scanning"); + pthread_mutex_unlock(&priv_sprd_v4l2->seek_cancel_mutex); + if (ret == -1) { + if (errno == EAGAIN) { + MMRADIO_LOG_ERROR("scanning timeout\n"); + } else if (errno == EINVAL) { + MMRADIO_LOG_ERROR("The tuner index is out of bounds or the value in the type field is wrong or we were asked to stop search"); + break; + } else { + MMRADIO_LOG_ERROR("Error: %s, %d\n", strerror(errno), errno); + break; + } + } + + /* now we can get new frequency from radio device */ + + if (radio->stop_scan) + break; + + ret = ioctl(radio->radio_fd, VIDIOC_G_FREQUENCY, &(priv_sprd_v4l2->vf)); + if (ret < 0) { + MMRADIO_LOG_ERROR("VIDIOC_G_FREQUENCY failed with %s during SEEK", strerror(errno)); + } else { + freq = RADIO_FREQ_FORMAT_GET((priv_sprd_v4l2->vf).frequency); + radio->freq = freq; /* update freq in handle */ + if (freq < prev_freq) { + MMRADIO_LOG_DEBUG("scanning wrapped around. stopping scan\n"); + break; + } + + if (freq == prev_freq) { + MMRADIO_LOG_ERROR("frequency is same we wrapped around, we are finished scanning"); + break; + } + + prev_freq = param.radio_scan.frequency = freq; + MMRADIO_LOG_DEBUG("scanning : new frequency : [%d]\n", param.radio_scan.frequency); + + /* drop if max freq is scanned */ + if (param.radio_scan.frequency == radio->region_setting.band_max) { + MMRADIO_LOG_DEBUG("%d freq is dropping...and stopping scan\n", param.radio_scan.frequency); + break; + } + if (radio->stop_scan) + break; /* doesn't need to post */ + + MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_INFO, ¶m); + } + } +FINISHED: + radio->scan_thread = 0; + + if (!radio->stop_scan) { + /*Clean up radio*/ + __mmradio_deinit_v4l2_device(radio); + } + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY); + + if (!radio->stop_scan) { + + /*if there were any volume changes, we better set them right here + * refer to PLM - P141022-00376*/ + { + int volume = 0; + ret = mm_sound_volume_get_value(VOLUME_TYPE_MEDIA, &volume); + if (ret) { + MMRADIO_LOG_ERROR("mm_sound_volume_get_value failed with [0x%x]", ret); + } else { + /*we are good to set volume here*/ + ret = __mmradio_set_volume(radio, volume); + if (ret) { + MMRADIO_LOG_ERROR("__mmradio_set_volume failed with [0x%x]", ret); + } + } + } + + MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_FINISH, NULL); + } + + MMRADIO_LOG_FLEAVE(); + + pthread_exit(NULL); + + return; +} + +static bool __is_tunable_frequency(mm_radio_t *radio, int freq) +{ + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + + if (freq == radio->region_setting.band_max || freq == radio->region_setting.band_min) + return MM_RADIO_FALSE; + + MMRADIO_LOG_FLEAVE(); + + return MM_RADIO_TRUE; +} + +static void __mmradio_seek_thread(mm_radio_t *radio) +{ + int ret = 0; + int freq = 0; + int volume = 0; + MMMessageParamType param = {0,}; + struct v4l2_hw_freq_seek vs = {0,}; + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + + vs.tuner = TUNER_INDEX; + vs.type = V4L2_TUNER_RADIO; + vs.wrap_around = DEFAULT_WRAP_AROUND; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio); + + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *)radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE_RETURN_VOID(priv_sprd_v4l2); + + /* 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); + + if (!radio->seek_cancel) { + MMRADIO_LOG_DEBUG("try to seek "); + pthread_mutex_lock(&priv_sprd_v4l2->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(&priv_sprd_v4l2->seek_cancel_mutex); + goto SEEK_FAILED; + } + ret = ioctl(radio->radio_fd, VIDIOC_S_HW_FREQ_SEEK, &vs); + MMRADIO_LOG_DEBUG("seek end"); + pthread_mutex_unlock(&priv_sprd_v4l2->seek_cancel_mutex); + if (ret == -1) { + if (errno == EAGAIN) { + /* FIXIT : we need retrying code here */ + MMRADIO_LOG_ERROR("seeking 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 Or we were asked to stop search."); + goto SEEK_FAILED; + } else { + MMRADIO_LOG_ERROR("Error: %s, %d\n", strerror(errno), errno); + goto SEEK_FAILED; + } + } + + /*seek -> scan causes sound fix to that issue*/ + if (radio->seek_cancel) { + goto SEEK_FAILED; + } + + /* now we can get new frequency from radio device */ + ret = ioctl(radio->radio_fd, VIDIOC_G_FREQUENCY, &(priv_sprd_v4l2->vf)); + if (ret < 0) { + MMRADIO_LOG_ERROR("VIDIOC_G_FREQUENCY failed with %s during SEEK", strerror(errno)); + goto SEEK_FAILED; + } else { + freq = RADIO_FREQ_FORMAT_GET((priv_sprd_v4l2->vf).frequency); + radio->freq = freq; /* update freq in handle */ + } + + MMRADIO_LOG_INFO("found frequency %d during seek\n", radio->freq); + + /* 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"); + goto SEEK_FAILED; + } + + if (__is_tunable_frequency(radio, freq)) {/* check if it's limit freq or not */ + /* now tune to new frequency */ + ret = _mmradio_set_frequency(radio, freq); + if (ret) { + MMRADIO_LOG_ERROR("failed to tune to new frequency\n"); + goto SEEK_FAILED; + } + } + MMRADIO_LOG_DEBUG("seek_unmute : [%d] seek_canel - [%d]\n", radio->seek_unmute, radio->seek_cancel); + 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 = _mmradio_unmute(radio); + if (ret) { + MMRADIO_LOG_ERROR("failed to un_mute failed\n"); + goto SEEK_FAILED; + } + radio->seek_unmute = MM_RADIO_FALSE; + } + + param.radio_scan.frequency = radio->prev_seek_freq = freq; + MMRADIO_LOG_DEBUG("seeking : new frequency : [%d]\n", param.radio_scan.frequency); + MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, ¶m); + } + + radio->seek_thread = 0; + radio->is_seeking = MM_RADIO_FALSE; + + /*if there were any volume changes, we better set them right here + * refer to PLM - P141022-00376*/ + mm_sound_volume_get_value(VOLUME_TYPE_MEDIA, &volume); + mm_sound_volume_set_value(VOLUME_TYPE_MEDIA, volume); + + MMRADIO_LOG_FLEAVE(); + + pthread_exit(NULL); + 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 = _mmradio_unmute(radio); + if (ret) { + MMRADIO_LOG_ERROR("failed to un_mute failed\n"); + } + radio->seek_unmute = MM_RADIO_FALSE; + } + /* freq -1 means it's failed to seek */ + param.radio_scan.frequency = -1; + MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, ¶m); + radio->is_seeking = MM_RADIO_FALSE; + + /*if there were any volume changes, we better set them right here + * refer to PLM - P141022-00376*/ + mm_sound_volume_get_value(VOLUME_TYPE_MEDIA, &volume); + mm_sound_volume_set_value(VOLUME_TYPE_MEDIA, volume); + + pthread_exit(NULL); + return; +} + +static bool __mmradio_post_message(mm_radio_t *radio, enum MMMessageType msgtype, MMMessageParamType *param) +{ + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + + if (!radio->msg_cb) { + MMRADIO_LOG_WARNING("failed to post a message\n"); + return MM_RADIO_FALSE; + } + + MMRADIO_LOG_DEBUG("address of msg_cb = %p\n", radio->msg_cb); + + radio->msg_cb(msgtype, param, radio->msg_cb_param); + + MMRADIO_LOG_FLEAVE(); + + return MM_RADIO_TRUE; +} + +static int __mmradio_check_state(mm_radio_t *radio, MMRadioCommand command) +{ + MMRadioStateType radio_state = MM_RADIO_STATE_NUM; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + + radio_state = __mmradio_get_state(radio); + + MMRADIO_LOG_DEBUG("incomming command = %d current state = %d\n", command, radio_state); + + switch (command) { + case MMRADIO_COMMAND_CREATE: { + if (radio_state != 0) + goto NO_OP; + } + break; + + case MMRADIO_COMMAND_REALIZE: { + if (radio_state == MM_RADIO_STATE_READY || + radio_state == MM_RADIO_STATE_PLAYING || + radio_state == MM_RADIO_STATE_SCANNING) + goto NO_OP; + + if (radio_state == 0) + goto INVALID_STATE; + } + break; + + case MMRADIO_COMMAND_UNREALIZE: { + if (radio_state == MM_RADIO_STATE_NULL) + goto NO_OP; + + /* we can call unrealize at any higher state */ + } + break; + + case MMRADIO_COMMAND_START: { + if (radio_state == MM_RADIO_STATE_PLAYING) + goto NO_OP; + + if (radio_state != MM_RADIO_STATE_READY) + goto INVALID_STATE; + } + break; + + case MMRADIO_COMMAND_STOP: { + if (radio_state == MM_RADIO_STATE_READY) + goto NO_OP; + + if (radio_state != MM_RADIO_STATE_PLAYING) + goto INVALID_STATE; + } + break; + + case MMRADIO_COMMAND_START_SCAN: { + if (radio_state == MM_RADIO_STATE_SCANNING) + goto NO_OP; + + if (radio_state != MM_RADIO_STATE_READY) + goto INVALID_STATE; + } + break; + + case MMRADIO_COMMAND_STOP_SCAN: { + if (radio_state == MM_RADIO_STATE_READY) + goto NO_OP; + + if (radio_state != MM_RADIO_STATE_SCANNING) + goto INVALID_STATE; + } + break; + + case MMRADIO_COMMAND_DESTROY: + case MMRADIO_COMMAND_VOLUME: + case MMRADIO_COMMAND_MUTE: + case MMRADIO_COMMAND_UNMUTE: + case MMRADIO_COMMAND_SET_FREQ: + case MMRADIO_COMMAND_GET_FREQ: + case MMRADIO_COMMAND_SET_REGION: { + /* we can do it at any state */ + } + break; + + case MMRADIO_COMMAND_SEEK: { + if (radio_state != MM_RADIO_STATE_PLAYING) + goto INVALID_STATE; + } + break; + + case MMRADIO_COMMAND_GET_REGION: { + if (radio_state == MM_RADIO_STATE_NULL) + goto INVALID_STATE; + } + break; + case MMRADIO_COMMAND_TUNE: { + if (radio_state < MM_RADIO_STATE_READY || radio_state >= MM_RADIO_STATE_NUM) + goto INVALID_STATE; + } + break; + case MMRADIO_COMMAND_RDS_START: { + if (radio_state != MM_RADIO_STATE_PLAYING) + goto INVALID_STATE; + } + break; + case MMRADIO_COMMAND_RDS_STOP: { + if (radio_state != MM_RADIO_STATE_PLAYING) + goto INVALID_STATE; + } + break; + default: + MMRADIO_LOG_DEBUG("not handled in FSM. don't care it\n"); + break; + } + + MMRADIO_LOG_DEBUG("status OK\n"); + + radio->cmd = command; + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; + + +INVALID_STATE: + MMRADIO_LOG_WARNING("invalid state. current = %d command = %d\n", + radio_state, command); + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_RADIO_INVALID_STATE; + + +NO_OP: + MMRADIO_LOG_WARNING("mm-radio is in the desired state(%d). doing noting\n", radio_state); + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_RADIO_NO_OP; + +} + +static bool __mmradio_set_state(mm_radio_t *radio, int new_state) +{ + MMMessageParamType msg = {0, }; + int msg_type = MM_MESSAGE_UNKNOWN; + + MMRADIO_LOG_FENTER(); + + if (!radio) { + MMRADIO_LOG_WARNING("calling set_state with invalid radio handle\n"); + return MM_RADIO_FALSE; + } + + if (radio->current_state == new_state && radio->pending_state == 0) { + MMRADIO_LOG_WARNING("we are in same state\n"); + return MM_RADIO_TRUE; + } + + /* set state */ + radio->old_state = radio->current_state; + radio->current_state = new_state; + + /* fill message param */ + msg.state.previous = radio->old_state; + msg.state.current = radio->current_state; + + /* post message to application */ + switch (radio->sm.by_asm_cb) { + case MMRADIO_ASM_CB_NONE: { + msg_type = MM_MESSAGE_STATE_CHANGED; + MMRADIO_POST_MSG(radio, MM_MESSAGE_STATE_CHANGED, &msg); + } + break; + + case MMRADIO_ASM_CB_POSTMSG: { + msg_type = MM_MESSAGE_STATE_INTERRUPTED; + msg.union_type = MM_MSG_UNION_CODE; + msg.code = radio->sm.event_src; + MMRADIO_POST_MSG(radio, MM_MESSAGE_STATE_INTERRUPTED, &msg); + } + break; + + case MMRADIO_ASM_CB_SKIP_POSTMSG: + default: + break; + } + + MMRADIO_LOG_FLEAVE(); + + return MM_RADIO_TRUE; +} + +static int __mmradio_get_state(mm_radio_t *radio) +{ + MMRADIO_CHECK_INSTANCE(radio); + + MMRADIO_LOG_DEBUG("radio state : current : [%d] old : [%d] pending : [%d]\n", + radio->current_state, radio->old_state, radio->pending_state); + + return radio->current_state; +} +#ifdef FEATURE_ASM_SUPPORT +static ASM_cb_result_t __mmradio_asm_callback(int handle, ASM_event_sources_t event_source, ASM_sound_commands_t command, unsigned int sound_status, void *cb_data) +{ + mm_radio_t *radio = (mm_radio_t *) cb_data; + int result = MM_ERROR_NONE; + ASM_cb_result_t cb_res = ASM_CB_RES_NONE; + + MMRADIO_LOG_FENTER(); + + radio->sm.event_src = event_source; + + switch (command) { + case ASM_COMMAND_STOP: { + MMRADIO_LOG_INFO("got ASM_COMMAND_STOP cmd. (cmd: %d event_src: %d)\n", command, event_source); + switch (event_source) { + case ASM_EVENT_SOURCE_CALL_START: + case ASM_EVENT_SOURCE_ALARM_START: + case ASM_EVENT_SOURCE_EMERGENCY_START: + case ASM_EVENT_SOURCE_EARJACK_UNPLUG: + case ASM_EVENT_SOURCE_MEDIA: + case ASM_EVENT_SOURCE_RESOURCE_CONFLICT: + case ASM_EVENT_SOURCE_NOTIFY_START: + case ASM_EVENT_SOURCE_OTHER_PLAYER_APP: + /* case ASM_EVENT_SOURCE_RESUMABLE_MEDIA: */ + { + radio->sm.by_asm_cb = MMRADIO_ASM_CB_POSTMSG; + result = _mmradio_stop(radio); + if (result) { + MMRADIO_LOG_ERROR("failed to stop radio\n"); + } + _mm_radio_event_s *event = g_slice_new0(_mm_radio_event_s); + if (event == NULL) { + cb_res = ASM_CB_RES_IGNORE; + return cb_res; + } + + event->event_type = MMRADIO_EVENT_STOP; + g_async_queue_push_sorted(radio->event_queue, event, event_comparator, NULL); + MMRADIO_LOG_DEBUG("unprepare in asm callback\n"); + radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE; + } + break; + default: { + radio->sm.by_asm_cb = MMRADIO_ASM_CB_SKIP_POSTMSG; + result = _mmradio_stop(radio); + if (result) { + MMRADIO_LOG_ERROR("failed to stop radio\n"); + } + _mm_radio_event_s *event = g_slice_new0(_mm_radio_event_s); + if (event == NULL) { + cb_res = ASM_CB_RES_IGNORE; + return cb_res; + } + + event->event_type = MMRADIO_EVENT_STOP; + g_async_queue_push_sorted(radio->event_queue, event, event_comparator, NULL); + radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE; + } + break; + } + cb_res = ASM_CB_RES_STOP; + } + break; + case ASM_COMMAND_PAUSE: { + MMRADIO_LOG_INFO("got ASM_COMMAND_PAUSE cmd. (cmd: %d event_src: %d)\n", command, event_source); + switch (event_source) { + case ASM_EVENT_SOURCE_CALL_START: + case ASM_EVENT_SOURCE_ALARM_START: + case ASM_EVENT_SOURCE_EMERGENCY_START: + case ASM_EVENT_SOURCE_EARJACK_UNPLUG: + case ASM_EVENT_SOURCE_MEDIA: + case ASM_EVENT_SOURCE_RESOURCE_CONFLICT: + case ASM_EVENT_SOURCE_NOTIFY_START: + case ASM_EVENT_SOURCE_OTHER_PLAYER_APP: + /* case ASM_EVENT_SOURCE_RESUMABLE_MEDIA: */ + { + radio->sm.by_asm_cb = MMRADIO_ASM_CB_POSTMSG; + result = _mmradio_pause(radio); + if (result) { + MMRADIO_LOG_ERROR("failed to pause radio\n"); + } + _mm_radio_event_s *event = g_slice_new0(_mm_radio_event_s); + if (event == NULL) { + cb_res = ASM_CB_RES_IGNORE; + return cb_res; + } + + event->event_type = MMRADIO_EVENT_STOP; + g_async_queue_push_sorted(radio->event_queue, event, event_comparator, NULL); + radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE; + } + break; +#if 0 + /* to handle timer recording with RADIO_INTERRUPTED_BY_RESUME_CANCEL */ + case ASM_EVENT_SOURCE_RESUMABLE_CANCELED: { + MMRadioStateType radio_cur_state = MM_RADIO_STATE_NUM; + radio_cur_state = __mmradio_get_state(radio); + radio->sm.by_asm_cb = MMRADIO_ASM_CB_POSTMSG; + if (radio_cur_state == MM_RADIO_STATE_READY) { + MMMessageParamType msg = {0, }; + int msg_type = MM_MESSAGE_UNKNOWN; + + msg_type = MM_MESSAGE_STATE_INTERRUPTED; + msg.union_type = MM_MSG_UNION_CODE; + msg.code = radio->sm.event_src; + MMRADIO_LOG_INFO("send RADIO_INTERRUPTED_BY_RESUME_CANCEL to clear timer. (cmd: %d event_src: %d)\n", command, event_source); + MMRADIO_POST_MSG(radio, MM_MESSAGE_STATE_INTERRUPTED, &msg); + } + radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE; + } + break; +#endif + default: { + MMRADIO_LOG_WARNING("ASM_COMMAND_PAUSE but event_source is %d\n", event_source); + radio->sm.by_asm_cb = MMRADIO_ASM_CB_SKIP_POSTMSG; + result = _mmradio_pause(radio); + if (result) { + MMRADIO_LOG_ERROR("failed to pause radio\n"); + } + _mm_radio_event_s *event = g_slice_new0(_mm_radio_event_s); + if (event == NULL) { + cb_res = ASM_CB_RES_IGNORE; + return cb_res; + } + + event->event_type = MMRADIO_EVENT_STOP; + g_async_queue_push_sorted(radio->event_queue, event, event_comparator, NULL); + radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE; + } + break; + } + cb_res = ASM_CB_RES_PAUSE; + } + break; + + case ASM_COMMAND_PLAY: + case ASM_COMMAND_RESUME: { + MMMessageParamType msg = {0,}; + msg.union_type = MM_MSG_UNION_CODE; + msg.code = event_source; + + if (command == ASM_COMMAND_PLAY) + MMRADIO_LOG_INFO("got ASM_COMMAND_PLAY (cmd: %d event_src: %d)\n", command, event_source); + else if (command == ASM_COMMAND_RESUME) + MMRADIO_LOG_INFO("got ASM_COMMAND_RESUME (cmd: %d event_src: %d)\n", command, event_source); + + MMRADIO_LOG_DEBUG("Got ASM resume message by %d\n", msg.code); + MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg); + + cb_res = ASM_CB_RES_IGNORE; + radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE; + } + break; + + default: + break; + } + + MMRADIO_LOG_FLEAVE(); + + return cb_res; +} +#else +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, + const char *additional_info, void *user_data) +{ + mm_radio_t *radio = (mm_radio_t *) user_data; + ASM_event_sources_t event_source; + int result = MM_ERROR_NONE; + int postMsg = false; + + MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_INSTANCE(radio); + + mmradio_get_audio_focus_reason(focus_state, reason_for_change, &event_source, &postMsg); + radio->sm.event_src = event_source; + + switch (focus_state) { + case FOCUS_IS_RELEASED: + radio->sm.by_asm_cb = MMRADIO_ASM_CB_POSTMSG; + result = _mmradio_stop(radio); + if (result) { + MMRADIO_LOG_ERROR("failed to stop radio\n"); + } + MMRADIO_LOG_DEBUG("FOCUS_IS_RELEASED\n"); + break; + + case FOCUS_IS_ACQUIRED: { + MMMessageParamType msg = {0,}; + msg.union_type = MM_MSG_UNION_CODE; + msg.code = event_source; + if (postMsg) + MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg); + + radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE; + + MMRADIO_LOG_DEBUG("FOCUS_IS_ACQUIRED\n"); + } + break; + + default: + MMRADIO_LOG_DEBUG("Unknown focus_state\n"); + break; + } + MMRADIO_LOG_FLEAVE(); +} + +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; + ASM_event_sources_t event_source; + int result = MM_ERROR_NONE; + int postMsg = false; + + MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_INSTANCE(radio); + + mmradio_get_audio_focus_reason(!focus_state, reason_for_change, &event_source, &postMsg); + radio->sm.event_src = event_source; + + switch (focus_state) { + case FOCUS_IS_RELEASED: { + MMMessageParamType msg = {0,}; + msg.union_type = MM_MSG_UNION_CODE; + msg.code = event_source; + if (postMsg) + MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg); + + radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE; + + MMRADIO_LOG_DEBUG("FOCUS_IS_ACQUIRED postMsg: %d\n", postMsg); + } + break; + + case FOCUS_IS_ACQUIRED: { + radio->sm.by_asm_cb = MMRADIO_ASM_CB_POSTMSG; + result = _mmradio_stop(radio); + if (result) { + MMRADIO_LOG_ERROR("failed to stop radio\n"); + } + MMRADIO_LOG_DEBUG("FOCUS_IS_RELEASED\n"); + break; + } + break; + + default: + MMRADIO_LOG_DEBUG("Unknown focus_state postMsg : %d\n", postMsg); + break; + } + MMRADIO_LOG_FLEAVE(); +} +#endif +int _mmradio_get_region_type(mm_radio_t *radio, MMRadioRegionType *type) +{ + MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION); + + return_val_if_fail(type, MM_ERROR_INVALID_ARGUMENT); + + *type = radio->region_setting.country; + + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_NONE; +} + +int _mmradio_get_region_frequency_range(mm_radio_t *radio, unsigned int *min_freq, unsigned int *max_freq) +{ + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION); + + return_val_if_fail(min_freq && max_freq, MM_ERROR_INVALID_ARGUMENT); + + *min_freq = radio->region_setting.band_min; + *max_freq = radio->region_setting.band_max; + + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_NONE; +} + +int _mmradio_get_channel_spacing(mm_radio_t *radio, unsigned int *ch_spacing) +{ + MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION); + + return_val_if_fail(ch_spacing, MM_ERROR_INVALID_ARGUMENT); + + *ch_spacing = radio->region_setting.channel_spacing; + + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_NONE; +} + +#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("avsysaudio"); + + radio->pGstreamer_s->avsysaudiosrc = gst_element_factory_make("avsysaudiosrc", "fm audio src"); + radio->pGstreamer_s->queue2 = gst_element_factory_make("queue2", "queue2"); + radio->pGstreamer_s->avsysaudiosink = gst_element_factory_make("avsysaudiosink", "audio sink"); + + g_object_set(radio->pGstreamer_s->avsysaudiosrc, "latency", 2, NULL); + g_object_set(radio->pGstreamer_s->avsysaudiosink, "sync", false, NULL); + + if (!radio->pGstreamer_s->pipeline || !radio->pGstreamer_s->avsysaudiosrc || !radio->pGstreamer_s->queue2 || !radio->pGstreamer_s->avsysaudiosink) { + mmf_debug(MMF_DEBUG_ERROR, "[%s][%05d] One element could not be created. Exiting.\n", __func__, __LINE__); + return MM_ERROR_RADIO_NOT_INITIALIZED; + } + + gst_bin_add_many(GST_BIN(radio->pGstreamer_s->pipeline), + radio->pGstreamer_s->avsysaudiosrc, + radio->pGstreamer_s->queue2, + radio->pGstreamer_s->avsysaudiosink, + NULL); + if (!gst_element_link_many( + radio->pGstreamer_s->avsysaudiosrc, + radio->pGstreamer_s->queue2, + radio->pGstreamer_s->avsysaudiosink, + NULL)) { + mmf_debug(MMF_DEBUG_ERROR, "[%s][%05d] Fail to link b/w appsrc and ffmpeg in rotate\n", __func__, __LINE__); + return MM_ERROR_RADIO_NOT_INITIALIZED; + } + 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) { + mmf_debug(MMF_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; + } + + ret_state = gst_element_get_state(radio->pGstreamer_s->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); + if (ret_state == GST_STATE_CHANGE_FAILURE) { + mmf_debug(MMF_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 { + mmf_debug(MMF_DEBUG_LOG, "[%s][%05d] GST_STATE_NULL ret_state = %d (GST_STATE_CHANGE_SUCCESS)\n", __func__, __LINE__, ret_state); + } + 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) { + mmf_debug(MMF_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; + } + + ret_state = gst_element_get_state(radio->pGstreamer_s->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); + if (ret_state == GST_STATE_CHANGE_FAILURE) { + mmf_debug(MMF_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 { + mmf_debug(MMF_DEBUG_LOG, "[%s][%05d] GST_STATE_NULL ret_state = %d (GST_STATE_CHANGE_SUCCESS)\n", __func__, __LINE__, ret_state); + } + return ret; +} + +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) { + mmf_debug(MMF_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; + } + + ret_state = gst_element_get_state(radio->pGstreamer_s->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); + if (ret_state == GST_STATE_CHANGE_FAILURE) { + mmf_debug(MMF_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 { + mmf_debug(MMF_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; +} +#endif + + +static int append_variant(DBusMessageIter *iter, const char *sig, char *param[]) +{ + char *ch; + int i; + int int_type; + unsigned long long int64_type; + + if (!sig || !param) + return 0; + + for (ch = (char *)sig, i = 0; *ch != '\0'; ++i, ++ch) { + switch (*ch) { + case 'i': + int_type = atoi(param[i]); + dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &int_type); + break; + case 'u': + int_type = atoi(param[i]); + dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &int_type); + break; + case 't': + int64_type = atoi(param[i]); + dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT64, &int64_type); + break; + case 's': + dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, ¶m[i]); + break; + default: + return -EINVAL; + } + } + + return 0; +} + +#define DESTINATION "org.tizen.system.deviced" +#define PATH "/Org/Tizen/System/DeviceD/Bluetooth" +#define INTERFACE "org.tizen.system.deviced.bluetooth" +#define METHOD_TURN_ON "TurnOn" +#define METHOD_TURN_OFF "TurnOff" +#define METHOD_GET_STATE "GetState" +#define BLUETOOTH_STATE_ACTIVE "active" +#define BLUETOOTH_STATE_INACTIVE "inactive" + +static int __mmradio_enable_bluetooth(mm_radio_t *radio, int enable) +{ + DBusConnection *conn; + DBusMessage *msg; + DBusMessageIter iter; + DBusMessage *reply; + DBusError err; + + int r; + const char *dest = DESTINATION; + const char *path = PATH; + const char *interface = INTERFACE; + const char *method = enable > 0 ? METHOD_TURN_ON : METHOD_TURN_OFF; + char *param[1]; + + conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); + if (!conn) { + MMRADIO_LOG_ERROR("dbus_bus_get error"); + return MM_ERROR_RADIO_INTERNAL; + } + + MMRADIO_LOG_INFO("try to send (%s, %s, %s, %s)", dest, path, interface, method); + + msg = dbus_message_new_method_call(dest, path, interface, method); + if (!msg) { + MMRADIO_LOG_ERROR("dbus_message_new_method_call(%s:%s-%s)", path, interface, method); + return MM_ERROR_RADIO_INTERNAL; + } + param[0] = "fmradio"; + + dbus_message_iter_init_append(msg, &iter); + r = append_variant(&iter, "s", param); + if (r < 0) { + MMRADIO_LOG_ERROR("append_variant error(%d)", r); + dbus_message_unref(msg); + return MM_ERROR_RADIO_INTERNAL; + } + + dbus_error_init(&err); + + reply = dbus_connection_send_with_reply_and_block(conn, msg, DBUS_TIMEOUT_USE_DEFAULT, &err); + if (!reply) { + MMRADIO_LOG_ERROR("dbus_connection_send error(No reply)"); + } + + if (dbus_error_is_set(&err)) { + MMRADIO_LOG_ERROR("dbus_connection_send error(%s:%s)", err.name, err.message); + dbus_message_unref(msg); + dbus_error_free(&err); + return MM_ERROR_RADIO_INTERNAL; + } + + dbus_message_unref(msg); + dbus_error_free(&err); + + return MM_ERROR_NONE; +} + +static int __mmradio_wait_bluetooth_ready(mm_radio_t *radio, int wait_active, int retry_count) +{ + DBusConnection *conn; + DBusMessage *msg = NULL; + DBusMessage *reply = NULL; + DBusError err; + + int ret = MM_ERROR_RADIO_INTERNAL; + const char *dest = DESTINATION; + const char *path = PATH; + const char *interface = INTERFACE; + const char *method = METHOD_GET_STATE; + const int wait = 100 * 1000; /* 100 msec */ + + conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); + if (!conn) { + MMRADIO_LOG_ERROR("dbus_bus_get error"); + goto error; + } + + MMRADIO_LOG_INFO("try to send (%s, %s, %s, %s)", dest, path, interface, method); + + msg = dbus_message_new_method_call(dest, path, interface, method); + if (!msg) { + MMRADIO_LOG_ERROR("dbus_message_new_method_call(%s:%s-%s)", path, interface, method); + goto error; + } + + while (retry_count--) { + dbus_error_init(&err); + reply = dbus_connection_send_with_reply_and_block(conn, msg, DBUS_TIMEOUT_USE_DEFAULT, &err); + if (!reply) { + MMRADIO_LOG_ERROR("dbus_connection_send error(No reply)"); + goto error; + } else { + const char *state; + /* if bluetooth is turn on by bt framework, it would be returned "active" */ + if (MM_RADIO_FALSE == dbus_message_get_args(reply, &err, DBUS_TYPE_STRING, &state, DBUS_TYPE_INVALID)) { + MMRADIO_LOG_ERROR("dbus_message_get_args error(%s:%s)", err.name, err.message); + goto error; + } + + if (wait_active == MM_RADIO_TRUE) { + MMRADIO_LOG_INFO("wait for active state. current state (%s)", state); + if (strncmp(BLUETOOTH_STATE_ACTIVE, state, strlen(BLUETOOTH_STATE_ACTIVE))) { + usleep(wait); + continue; + } else { + ret = MM_ERROR_NONE; + break; + } + } else { + MMRADIO_LOG_INFO("wait for inactive state. current state (%s)", state); + if (strncmp(BLUETOOTH_STATE_INACTIVE, state, strlen(BLUETOOTH_STATE_INACTIVE))) { + usleep(wait); + ret = MM_ERROR_RADIO_INVALID_STATE; + break; + } else { + ret = MM_ERROR_NONE; + break; + } + } + } + } + + +error: + if (dbus_error_is_set(&err)) { + MMRADIO_LOG_ERROR("dbus_connection_send error(%s:%s)", err.name, err.message); + reply = NULL; + } + + if (msg != NULL) + dbus_message_unref(msg); + dbus_error_free(&err); + + return ret; + +} + + + + +int _mm_radio_load_volume_table(int **volume_table, int *number_of_elements) +{ + dictionary *dict = NULL; + const char delimiter[] = ", "; + char *ptr = NULL; + char *token = NULL; + char *list_str = NULL; + int *temp_table = NULL; + int index = 0; + int ret = 0; + + bool tuning_enable = MM_RADIO_FALSE; + int not_found = -1; + int value = 0; + + dict = iniparser_load(MMFW_RADIO_TUNING_DEFUALT_FILE); + if (dict == NULL) { + MMRADIO_LOG_ERROR("%s load failed", MMFW_RADIO_TUNING_DEFUALT_FILE); + return MM_ERROR_RADIO_INTERNAL; + } else { + /*tuning enable */ + value = iniparser_getboolean(dict, MMFW_RADIO_TUNING_ENABLE, not_found); + if (value == not_found) { + MMRADIO_LOG_ERROR("Can't get Tuning Enable value"); + } else { + tuning_enable = value; + MMRADIO_LOG_INFO("Tuning enabled."); + } + + iniparser_freedict(dict); /*Cleanup*/ + } + + + if (tuning_enable == MM_RADIO_TRUE) { + dict = iniparser_load(MMFW_RADIO_TUNING_TEMP_FILE); + if (!dict) { + MMRADIO_LOG_WARNING("%s load failed. Use temporary file", MMFW_RADIO_TUNING_TEMP_FILE); + dict = iniparser_load(MMFW_RADIO_TUNING_DEFUALT_FILE); + if (!dict) { + MMRADIO_LOG_ERROR("%s load failed", MMFW_RADIO_TUNING_DEFUALT_FILE); + return MM_ERROR_RADIO_INTERNAL; + } + } + } else { + dict = iniparser_load(MMFW_RADIO_TUNING_DEFUALT_FILE); + if (!dict) { + MMRADIO_LOG_ERROR("%s load failed", MMFW_RADIO_TUNING_DEFUALT_FILE); + return MM_ERROR_RADIO_INTERNAL; + } + } + + *number_of_elements = iniparser_getint(dict, MMFW_RADIO_TUNING_VOLUME_LEVELS, -1); + if (*number_of_elements == -1) { + ret = MM_ERROR_INVALID_ARGUMENT; + goto error; + } + temp_table = (int *)malloc((*number_of_elements) * sizeof(int)); + if (!temp_table) { + goto error; + } + *volume_table = temp_table; + + list_str = iniparser_getstr(dict, MMFW_RADIO_TUNING_VOLUME_TABLE); + if (list_str) { + token = strtok_r(list_str, delimiter, &ptr); + while (token) { + temp_table[index] = atoi(token); + MMRADIO_LOG_INFO("fm volume index %d is %d", index, temp_table[index]); + index++; + token = strtok_r(NULL, delimiter, &ptr); + } + } +error: + iniparser_freedict(dict); + return ret; +} + +int _mmradio_get_device_available(mm_radio_t *radio , bool *is_connected) +{ + mm_sound_device_flags_e flags = MM_SOUND_DEVICE_STATE_ACTIVATED_FLAG; + MMSoundDeviceList_t device_list; + MMSoundDevice_t device_h = NULL; + mm_sound_device_type_e device_type; + mm_sound_device_type_e current_device = MM_SOUND_DEVICE_TYPE_BUILTIN_SPEAKER; + int ret = MM_ERROR_NONE; + + MMRADIO_LOG_FENTER(); + + /* get status if speaker is activated */ + /* (1) get current device list */ + ret = mm_sound_get_current_device_list(flags, &device_list); + if (ret) { + MMRADIO_LOG_FLEAVE(); + MMRADIO_LOG_DEBUG("mm_sound_get_current_device_list() failed [%x]!!", ret); + return MM_ERROR_RADIO_NO_ANTENNA; + } + + while (current_device <= MM_SOUND_DEVICE_TYPE_USB_AUDIO) { + /* (2) get device handle of device list */ + ret = mm_sound_get_next_device(device_list, &device_h); + + if (ret) { + MMRADIO_LOG_DEBUG("mm_sound_get_next_device() failed [%x]!!", ret); + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_RADIO_NO_ANTENNA; + } + + /* (3) get device type */ + ret = mm_sound_get_device_type(device_h, &device_type); + + if (ret) { + MMRADIO_LOG_DEBUG("mm_sound_get_device_type() failed [%x]!!", ret); + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_RADIO_NO_ANTENNA; + } + + MMRADIO_LOG_DEBUG("device_type [%d]!!", device_type); + if (device_type == MM_SOUND_DEVICE_TYPE_AUDIOJACK) { + *is_connected = TRUE; + return MM_ERROR_NONE; + } + + current_device++; + } + + MMRADIO_LOG_DEBUG("ret [%d] is_connected : %d!!", ret, *is_connected); + MMRADIO_LOG_FLEAVE(); + + return ret; + +} + diff --git a/src/mm_radio_priv_emulator.c b/src/mm_radio_priv_emulator.c index 8dff4b2..d6ee219 100644 --- a/src/mm_radio_priv_emulator.c +++ b/src/mm_radio_priv_emulator.c @@ -67,10 +67,11 @@ #define FREQ_FRAC 16 #define RADIO_FREQ_FORMAT_SET(x_freq) ((x_freq) * FREQ_FRAC) #define RADIO_FREQ_FORMAT_GET(x_freq) ((x_freq) / FREQ_FRAC) -#define DEFAULT_WRAP_AROUND 1 //If non-zero, wrap around when at the end of the frequency range, else stop seeking +#define DEFAULT_WRAP_AROUND 1 /*If non-zero, wrap around when at the end of the frequency range, else stop seeking */ #define RADIO_DEFAULT_REGION MM_RADIO_REGION_GROUP_USA #define EMULATOR_FREQ_MAX 5 + /*--------------------------------------------------------------------------- LOCAL CONSTANT DEFINITIONS: ---------------------------------------------------------------------------*/ @@ -88,45 +89,53 @@ extern int errno; LOCAL VARIABLE DEFINITIONS: ---------------------------------------------------------------------------*/ /* radio region configuration table */ -static const MMRadioRegion_t region_table[] = -{ - { /* Notrh America, South America, South Korea, Taiwan, Australia */ - MM_RADIO_REGION_GROUP_USA, // region type - MM_RADIO_DEEMPHASIS_75_US, // de-emphasis - MM_RADIO_FREQ_MIN_87500_KHZ, // min freq. - MM_RADIO_FREQ_MAX_108000_KHZ, // max freq. - }, - { /* China, Europe, Africa, Middle East, Hong Kong, India, Indonesia, Russia, Singapore */ - MM_RADIO_REGION_GROUP_EUROPE, - MM_RADIO_DEEMPHASIS_50_US, - MM_RADIO_FREQ_MIN_87500_KHZ, - MM_RADIO_FREQ_MAX_108000_KHZ, - }, - { - MM_RADIO_REGION_GROUP_JAPAN, - MM_RADIO_DEEMPHASIS_50_US, - MM_RADIO_FREQ_MIN_76100_KHZ, - MM_RADIO_FREQ_MAX_89900_KHZ, - }, +static const MMRadioRegion_t region_table[] = { + { /* Notrh America, South America, South Korea, Taiwan, Australia */ + MM_RADIO_REGION_GROUP_USA, /* region type */ + MM_RADIO_DEEMPHASIS_75_US, /* de-emphasis */ + MM_RADIO_FREQ_MIN_87500_KHZ, /* min freq. */ + MM_RADIO_FREQ_MAX_108000_KHZ, /* max freq. */ + 50, + }, + { /* China, Europe, Africa, Middle East, Hong Kong, India, Indonesia, Russia, Singapore */ + MM_RADIO_REGION_GROUP_EUROPE, + MM_RADIO_DEEMPHASIS_50_US, + MM_RADIO_FREQ_MIN_87500_KHZ, + MM_RADIO_FREQ_MAX_108000_KHZ, + 50, + }, + { + MM_RADIO_REGION_GROUP_JAPAN, + MM_RADIO_DEEMPHASIS_50_US, + MM_RADIO_FREQ_MIN_76100_KHZ, + MM_RADIO_FREQ_MAX_89900_KHZ, + 50, + }, }; static int MMRadioEmulatorFreq[EMULATOR_FREQ_MAX] = { - 89100,89900,91900,99900,107700}; + 89100, 89900, 91900, 99900, 107700 +}; static int EmultatorIdx = 0; /*--------------------------------------------------------------------------- LOCAL FUNCTION PROTOTYPES: ---------------------------------------------------------------------------*/ -static bool __mmradio_post_message(mm_radio_t* radio, enum MMMessageType msgtype, MMMessageParamType* param); -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); -static void __mmradio_seek_thread(mm_radio_t* radio); -static void __mmradio_scan_thread(mm_radio_t* radio); -ASM_cb_result_t __mmradio_asm_callback(int handle, ASM_event_sources_t sound_event, ASM_sound_commands_t command, unsigned int sound_status, void* cb_data); -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 bool __mmradio_post_message(mm_radio_t *radio, enum MMMessageType msgtype, MMMessageParamType *param); +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); +static void __mmradio_seek_thread(mm_radio_t *radio); +static void __mmradio_scan_thread(mm_radio_t *radio); +#ifdef FEATURE_ASM_SUPPORT +ASM_cb_result_t __mmradio_asm_callback(int handle, ASM_event_sources_t sound_event, ASM_sound_commands_t command, unsigned int sound_status, void *cb_data); +#else +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, const char *additional_info, void *user_data); +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 +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); /*=========================================================================== FUNCTION DEFINITIONS @@ -141,7 +150,7 @@ static int __mmradio_get_wave_num(mm_radio_t *radio); * Return : zero on success, or negative value with error code *---------------------------------------------------------------------------*/ int -_mmradio_apply_region(mm_radio_t* radio, MMRadioRegionType region, bool update) +_mmradio_apply_region(mm_radio_t *radio, MMRadioRegionType region, bool update) { int ret = MM_ERROR_NONE; int count = 0; @@ -149,41 +158,38 @@ _mmradio_apply_region(mm_radio_t* radio, MMRadioRegionType region, bool update) MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); - MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_SET_REGION ); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_REGION); /* if needed, radio region must be updated. * Otherwise, just applying settings to device without it. */ - if ( update ) - { + if (update) { count = ARRAY_SIZE(region_table); - //TODO: if auto is supported...get the region info. here + /*TODO: if auto is supported...get the region info. here */ /* update radio region settings */ - for ( index = 0; index < count; index++ ) - { + for (index = 0; index < count; index++) { /* find the region from pre-defined table*/ - if (region_table[index].country == region) - { + if (region_table[index].country == region) { radio->region_setting.country = region_table[index].country; radio->region_setting.deemphasis = region_table[index].deemphasis; radio->region_setting.band_min = region_table[index].band_min; radio->region_setting.band_max = region_table[index].band_max; + radio->region_setting.channel_spacing = region_table[index].channel_spacing; } } } /* chech device is opened or not. if it's not ready, skip to apply region to device now*/ - if (radio->radio_fd < 0) - { + if (radio->radio_fd < 0) { MMRADIO_LOG_DEBUG("not opened device. just updating region info. \n"); return MM_ERROR_NONE; } MMRADIO_SLOG_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); + 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); @@ -201,14 +207,14 @@ _mmradio_apply_region(mm_radio_t* radio, MMRadioRegionType region, bool update) } int -_mmradio_create_radio(mm_radio_t* radio) +_mmradio_create_radio(mm_radio_t *radio) { int ret = 0; MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); - MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_CREATE ); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_CREATE); /* set default value */ radio->radio_fd = -1; @@ -216,41 +222,43 @@ _mmradio_create_radio(mm_radio_t* radio) memset(&radio->region_setting, 0, sizeof(MMRadioRegion_t)); /* create command lock */ - ret = pthread_mutex_init( &radio->cmd_lock, NULL ); - if ( ret ) - { + ret = pthread_mutex_init(&radio->cmd_lock, NULL); + if (ret) { MMRADIO_LOG_ERROR("mutex creation failed\n"); return MM_ERROR_RADIO_INTERNAL; } - MMRADIO_SET_STATE( radio, MM_RADIO_STATE_NULL ); + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_NULL); /* register to ASM */ - ret = mmradio_asm_register(&radio->sm, __mmradio_asm_callback, (void*)radio); - if ( ret ) - { +#ifdef FEATURE_ASM_SUPPORT + ret = mmradio_asm_register(&radio->sm, __mmradio_asm_callback, (void *)radio); +#else + ret = mmradio_audio_focus_register(&radio->sm, _mmradio_sound_focus_cb, (void *)radio); +#endif + if (ret) { /* NOTE : we are dealing it as an error since we cannot expect it's behavior */ MMRADIO_LOG_ERROR("failed to register asm server\n"); return MM_ERROR_RADIO_INTERNAL; } + MMRADIO_LOG_FLEAVE(); return MM_ERROR_NONE; } int -_mmradio_realize(mm_radio_t* radio) +_mmradio_realize(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_REALIZE ); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_REALIZE); /* open radio device */ - if(radio->radio_fd == -1) - { + if (radio->radio_fd == -1) { MMRadioRegionType region = MM_RADIO_REGION_GROUP_NONE; bool update = false; @@ -260,14 +268,11 @@ _mmradio_realize(mm_radio_t* radio) MMRADIO_LOG_DEBUG("radio device fd : %d\n", radio->radio_fd); /* check region country type if it's updated or not */ - if ( radio->region_setting.country == MM_RADIO_REGION_GROUP_NONE) - { + 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 - { + } else { /* already initialized by application */ region = radio->region_setting.country; } @@ -277,13 +282,13 @@ _mmradio_realize(mm_radio_t* radio) } /* ready but nosound */ -// if( _mmradio_mute(radio) != MM_ERROR_NONE) -// goto error; + /* if( _mmradio_mute(radio) != MM_ERROR_NONE) */ + /* goto error; */ - MMRADIO_SET_STATE( radio, MM_RADIO_STATE_READY ); + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY); #ifdef USE_GST_PIPELINE ret = _mmradio_realize_pipeline(radio); - if ( ret ) { + if (ret) { debug_error("_mmradio_realize_pipeline is failed\n"); return ret; } @@ -293,8 +298,7 @@ _mmradio_realize(mm_radio_t* radio) return MM_ERROR_NONE; error: - if (radio->radio_fd >= 0) - { + if (radio->radio_fd >= 0) { radio->radio_fd = -1; } @@ -304,28 +308,30 @@ error: } int -_mmradio_unrealize(mm_radio_t* radio) +_mmradio_unrealize(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_UNREALIZE ); + 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; + /* if( _mmradio_mute(radio) != MM_ERROR_NONE) */ + /* return MM_ERROR_RADIO_NOT_INITIALIZED; */ /* close radio device here !!!! */ - if (radio->radio_fd >= 0) - { + if (radio->radio_fd >= 0) { radio->radio_fd = -1; } - MMRADIO_SET_STATE( radio, MM_RADIO_STATE_NULL ); + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_NULL); +#ifndef FEATURE_ASM_SUPPORT + ret = mmradio_set_audio_focus(&radio->sm, _mmradio_sound_focus_watch_cb, FALSE, (void *)radio); +#endif #ifdef USE_GST_PIPELINE - ret= _mmradio_destroy_pipeline(radio); - if ( ret ) { + ret = _mmradio_destroy_pipeline(radio); + if (ret) { debug_error("_mmradio_destroy_pipeline is failed\n"); return ret; } @@ -337,22 +343,25 @@ _mmradio_unrealize(mm_radio_t* radio) } int -_mmradio_destroy(mm_radio_t* radio) +_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 ); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_DESTROY); +#ifdef FEATURE_ASM_SUPPORT ret = mmradio_asm_deregister(&radio->sm); - if ( ret ) - { +#else + ret = mmradio_audio_focus_deregister(&radio->sm); +#endif + if (ret) { MMRADIO_LOG_ERROR("failed to deregister asm server\n"); return MM_ERROR_RADIO_INTERNAL; } - _mmradio_unrealize( radio ); + _mmradio_unrealize(radio); MMRADIO_LOG_FLEAVE(); @@ -361,40 +370,38 @@ _mmradio_destroy(mm_radio_t* radio) int -_mmradio_set_frequency(mm_radio_t* radio, int freq) // unit should be KHz +_mmradio_set_frequency(mm_radio_t *radio, int freq) /* unit should be KHz */ { int ret = 0; MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); - MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_SET_FREQ ); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_FREQ); MMRADIO_SLOG_DEBUG("Setting %d frequency\n", freq); MMRADIO_LOG_DEBUG("radio->freq: %d freq: %d\n", radio->freq, freq); - if (radio->radio_fd < 0) - { + 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 ) - { + 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; } radio->freq = freq; - if(radio->pGstreamer_s) - { +#ifdef USE_GST_PIPELINE + if (radio->pGstreamer_s) { int val = 0; val = __mmradio_get_wave_num(radio); - g_object_set(radio->pGstreamer_s->avsysaudiosrc, "wave", val, NULL); + g_object_set(radio->pGstreamer_s->audiosrc, "wave", val, NULL); } - +#endif MMRADIO_LOG_FLEAVE(); return MM_ERROR_NONE; @@ -402,19 +409,18 @@ _mmradio_set_frequency(mm_radio_t* radio, int freq) // unit should be KHz } int -_mmradio_get_frequency(mm_radio_t* radio, int* pFreq) +_mmradio_get_frequency(mm_radio_t *radio, int *pFreq) { int freq = 0; MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); - MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_GET_FREQ ); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_FREQ); - return_val_if_fail( pFreq, MM_ERROR_INVALID_ARGUMENT ); + return_val_if_fail(pFreq, MM_ERROR_INVALID_ARGUMENT); /* just return stored frequency if radio device is not ready */ - if ( radio->radio_fd < 0 ) - { + if (radio->radio_fd < 0) { MMRADIO_SLOG_DEBUG("freq : %d\n", radio->freq); *pFreq = radio->freq; return MM_ERROR_NONE; @@ -429,23 +435,23 @@ _mmradio_get_frequency(mm_radio_t* radio, int* pFreq) } int -_mmradio_mute(mm_radio_t* radio) +_mmradio_mute(mm_radio_t *radio) { MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); - MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_MUTE ); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_MUTE); - if (radio->radio_fd < 0) - { + if (radio->radio_fd < 0) { return MM_ERROR_RADIO_NOT_INITIALIZED; } - if(radio->pGstreamer_s){ +#ifdef USE_GST_PIPELINE + if (radio->pGstreamer_s) { g_object_set(radio->pGstreamer_s->volume, "mute", 1, NULL); MMRADIO_LOG_DEBUG("g_object set mute\n"); } - +#endif MMRADIO_LOG_FLEAVE(); return MM_ERROR_NONE; @@ -453,18 +459,20 @@ _mmradio_mute(mm_radio_t* radio) } int -_mmradio_unmute(mm_radio_t* radio) +_mmradio_unmute(mm_radio_t *radio) { MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); - MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_UNMUTE ); - MMRADIO_CHECK_DEVICE_STATE( radio ); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_UNMUTE); + MMRADIO_CHECK_DEVICE_STATE(radio); - if(radio->pGstreamer_s){ +#ifdef USE_GST_PIPELINE + if (radio->pGstreamer_s) { g_object_set(radio->pGstreamer_s->volume, "mute", 0, NULL); MMRADIO_LOG_DEBUG("g_object set un-mute\n"); } +#endif MMRADIO_LOG_FLEAVE(); @@ -479,23 +487,22 @@ _mmradio_unmute(mm_radio_t* radio) * Return : zero on success, or negative value with error code *---------------------------------------------------------------------------*/ int -__mmradio_set_deemphasis(mm_radio_t* radio) +__mmradio_set_deemphasis(mm_radio_t *radio) { int value = 0; MMRADIO_LOG_FENTER(); return MM_ERROR_NONE; - MMRADIO_CHECK_INSTANCE( radio ); + MMRADIO_CHECK_INSTANCE(radio); /* get de-emphasis */ - switch (radio->region_setting.deemphasis) - { + switch (radio->region_setting.deemphasis) { case MM_RADIO_DEEMPHASIS_50_US: - value = 1;//V4L2_DEEMPHASIS_50_uS; + value = 1;/*V4L2_DEEMPHASIS_50_uS; */ break; case MM_RADIO_DEEMPHASIS_75_US: - value = 2;//V4L2_DEEMPHASIS_75_uS; + value = 2;/*V4L2_DEEMPHASIS_75_uS; */ break; default: @@ -504,11 +511,10 @@ __mmradio_set_deemphasis(mm_radio_t* radio) } /* set it to device */ - (radio->vctrl).id = (0x009d0000 | 0x900) +1;//V4L2_CID_TUNE_DEEMPHASIS; + (radio->vctrl).id = (0x009d0000 | 0x900) + 1; /*V4L2_CID_TUNE_DEEMPHASIS; */ (radio->vctrl).value = value; - if (ioctl(radio->radio_fd, VIDIOC_S_CTRL, &(radio->vctrl)) < 0) - { + 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; } @@ -526,19 +532,18 @@ __mmradio_set_deemphasis(mm_radio_t* radio) * Return : zero on success, or negative value with error code *---------------------------------------------------------------------------*/ int -__mmradio_set_band_range(mm_radio_t* radio) +__mmradio_set_band_range(mm_radio_t *radio) { MMRADIO_LOG_FENTER(); return MM_ERROR_NONE; - MMRADIO_CHECK_INSTANCE( radio ); + 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 ) - { + 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; } @@ -549,11 +554,11 @@ __mmradio_set_band_range(mm_radio_t* radio) } int -_mmradio_set_message_callback(mm_radio_t* radio, MMMessageCallback callback, void *user_param) +_mmradio_set_message_callback(mm_radio_t *radio, MMMessageCallback callback, void *user_param) { MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); + MMRADIO_CHECK_INSTANCE(radio); radio->msg_cb = callback; radio->msg_cb_param = user_param; @@ -566,16 +571,16 @@ _mmradio_set_message_callback(mm_radio_t* radio, MMMessageCallback callback, voi } int -_mmradio_get_state(mm_radio_t* radio, int* pState) +_mmradio_get_state(mm_radio_t *radio, int *pState) { int state = 0; MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); - return_val_if_fail( pState, MM_ERROR_INVALID_ARGUMENT ); + MMRADIO_CHECK_INSTANCE(radio); + return_val_if_fail(pState, MM_ERROR_INVALID_ARGUMENT); - state = __mmradio_get_state( radio ); + state = __mmradio_get_state(radio); *pState = state; @@ -585,35 +590,38 @@ _mmradio_get_state(mm_radio_t* radio, int* pState) } int -_mmradio_start(mm_radio_t* radio) +_mmradio_start(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_START ); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_START); MMRADIO_SLOG_DEBUG("now tune to frequency : %d\n", radio->freq); +#ifdef FEATURE_ASM_SUPPORT ret = mmradio_asm_set_state(&radio->sm, ASM_STATE_PLAYING, ASM_RESOURCE_RADIO_TUNNER); - if ( ret ) - { - MMRADIO_LOG_ERROR("failed to set asm state to PLAYING\n"); +#else + ret = mmradio_set_audio_focus(&radio->sm, _mmradio_sound_focus_watch_cb, TRUE, (void *)radio); +#endif + if (ret) { + MMRADIO_LOG_ERROR("failed to set asm state to PLAYING or audio focus\n"); return ret; } /* set stored frequency */ - _mmradio_set_frequency( radio, radio->freq ); + _mmradio_set_frequency(radio, radio->freq); /* unmute */ -// if( _mmradio_unmute(radio) != MM_ERROR_NONE) -// return MM_ERROR_RADIO_NOT_INITIALIZED; + /* if( _mmradio_unmute(radio) != MM_ERROR_NONE) */ + /* return MM_ERROR_RADIO_NOT_INITIALIZED; */ - MMRADIO_SET_STATE( radio, MM_RADIO_STATE_PLAYING ); + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_PLAYING); #ifdef USE_GST_PIPELINE - ret = _mmradio_start_pipeline( radio ); - if ( ret ) { + ret = _mmradio_start_pipeline(radio); + if (ret) { debug_error("_mmradio_start_pipeline is failed\n"); return ret; } @@ -625,29 +633,31 @@ _mmradio_start(mm_radio_t* radio) } int -_mmradio_stop(mm_radio_t* radio) +_mmradio_stop(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_STOP ); + 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; + /* if( _mmradio_mute(radio) != MM_ERROR_NONE) */ + /* return MM_ERROR_RADIO_NOT_INITIALIZED; */ - MMRADIO_SET_STATE( radio, MM_RADIO_STATE_READY ); + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY); +#ifdef FEATURE_ASM_SUPPORT ret = mmradio_asm_set_state(&radio->sm, ASM_STATE_STOP, ASM_RESOURCE_NONE); - if ( ret ) - { +#endif + + if (ret) { MMRADIO_LOG_ERROR("failed to set asm state to PLAYING\n"); return ret; } #ifdef USE_GST_PIPELINE - ret= _mmradio_stop_pipeline( radio ); - if ( ret ) { + ret = _mmradio_stop_pipeline(radio); + if (ret) { debug_error("_mmradio_stop_pipeline is failed\n"); return ret; } @@ -660,42 +670,42 @@ _mmradio_stop(mm_radio_t* radio) #ifdef USE_GST_PIPELINE int -_mmradio_realize_pipeline(mm_radio_t* radio) +_mmradio_realize_pipeline(mm_radio_t *radio) { int ret = MM_ERROR_NONE; int val = 0; MMRADIO_LOG_FENTER(); - gst_init (NULL, NULL); - radio->pGstreamer_s = g_new0 (mm_radio_gstreamer_s, 1); + 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->pipeline = gst_pipeline_new("fmradio"); - radio->pGstreamer_s->avsysaudiosrc= gst_element_factory_make("audiotestsrc","fm audio src"); - radio->pGstreamer_s->queue2= gst_element_factory_make("queue2","queue2"); - radio->pGstreamer_s->volume= gst_element_factory_make("volume","volume"); - radio->pGstreamer_s->avsysaudiosink= gst_element_factory_make("pulsesink","audio sink"); + radio->pGstreamer_s->audiosrc = gst_element_factory_make("audiotestsrc", "fm audio src"); + radio->pGstreamer_s->queue2 = gst_element_factory_make("queue2", "queue2"); + radio->pGstreamer_s->volume = gst_element_factory_make("volume", "volume"); + radio->pGstreamer_s->audiosink = gst_element_factory_make("pulsesink", "audio sink"); val = __mmradio_get_wave_num(radio); - g_object_set(radio->pGstreamer_s->avsysaudiosrc, "wave", val, "volume", 0.8, NULL); + g_object_set(radio->pGstreamer_s->audiosrc, "wave", val, "volume", 0.8, NULL); - if (!radio->pGstreamer_s->pipeline || !radio->pGstreamer_s->avsysaudiosrc || !radio->pGstreamer_s->queue2 || !radio->pGstreamer_s->volume || !radio->pGstreamer_s->avsysaudiosink) { + if (!radio->pGstreamer_s->pipeline || !radio->pGstreamer_s->audiosrc || !radio->pGstreamer_s->queue2 || !radio->pGstreamer_s->volume || !radio->pGstreamer_s->audiosink) { MMRADIO_LOG_DEBUG("[%s][%05d] One element could not be created. Exiting.\n", __func__, __LINE__); return MM_ERROR_RADIO_NOT_INITIALIZED; } gst_bin_add_many(GST_BIN(radio->pGstreamer_s->pipeline), - radio->pGstreamer_s->avsysaudiosrc, - radio->pGstreamer_s->queue2, - radio->pGstreamer_s->volume, - radio->pGstreamer_s->avsysaudiosink, - NULL); - if(!gst_element_link_many( - radio->pGstreamer_s->avsysaudiosrc, - radio->pGstreamer_s->queue2, - radio->pGstreamer_s->volume, - radio->pGstreamer_s->avsysaudiosink, - NULL)) { - MMRADIO_LOG_DEBUG(,"[%s][%05d] Fail to link b/w appsrc and ffmpeg in rotate\n", __func__, __LINE__); + radio->pGstreamer_s->audiosrc, + radio->pGstreamer_s->queue2, + radio->pGstreamer_s->volume, + radio->pGstreamer_s->audiosink, + NULL); + if (!gst_element_link_many( + radio->pGstreamer_s->audiosrc, + radio->pGstreamer_s->queue2, + radio->pGstreamer_s->volume, + radio->pGstreamer_s->audiosink, + NULL)) { + MMRADIO_LOG_DEBUG(, "[%s][%05d] Fail to link b/w appsrc and ffmpeg in rotate\n", __func__, __LINE__); return MM_ERROR_RADIO_NOT_INITIALIZED; } MMRADIO_LOG_FLEAVE(); @@ -703,25 +713,25 @@ _mmradio_realize_pipeline(mm_radio_t* radio) } int -_mmradio_start_pipeline(mm_radio_t* radio) +_mmradio_start_pipeline(mm_radio_t *radio) { int ret = MM_ERROR_NONE; GstStateChangeReturn ret_state; MMRADIO_LOG_FENTER(); - if(gst_element_set_state (radio->pGstreamer_s->pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) { + if (gst_element_set_state(radio->pGstreamer_s->pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) { MMRADIO_LOG_DEBUG("Fail to change pipeline state"); - gst_object_unref (radio->pGstreamer_s->pipeline); - g_free (radio->pGstreamer_s); + gst_object_unref(radio->pGstreamer_s->pipeline); + g_free(radio->pGstreamer_s); return MM_ERROR_RADIO_INVALID_STATE; } - ret_state = gst_element_get_state (radio->pGstreamer_s->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); + ret_state = gst_element_get_state(radio->pGstreamer_s->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); if (ret_state == GST_STATE_CHANGE_FAILURE) { MMRADIO_LOG_DEBUG("GST_STATE_CHANGE_FAILURE"); - gst_object_unref (radio->pGstreamer_s->pipeline); - g_free (radio->pGstreamer_s); + gst_object_unref(radio->pGstreamer_s->pipeline); + g_free(radio->pGstreamer_s); return MM_ERROR_RADIO_INVALID_STATE; } else { MMRADIO_LOG_DEBUG("[%s][%05d] GST_STATE_NULL ret_state = %d (GST_STATE_CHANGE_SUCCESS)\n", __func__, __LINE__, ret_state); @@ -731,24 +741,24 @@ _mmradio_start_pipeline(mm_radio_t* radio) return ret; } int -_mmradio_stop_pipeline(mm_radio_t* radio) +_mmradio_stop_pipeline(mm_radio_t *radio) { int ret = MM_ERROR_NONE; GstStateChangeReturn ret_state; MMRADIO_LOG_FENTER(); - if(gst_element_set_state (radio->pGstreamer_s->pipeline, GST_STATE_READY) == GST_STATE_CHANGE_FAILURE) { + if (gst_element_set_state(radio->pGstreamer_s->pipeline, GST_STATE_READY) == GST_STATE_CHANGE_FAILURE) { MMRADIO_LOG_DEBUG("Fail to change pipeline state"); - gst_object_unref (radio->pGstreamer_s->pipeline); - g_free (radio->pGstreamer_s); + gst_object_unref(radio->pGstreamer_s->pipeline); + g_free(radio->pGstreamer_s); return MM_ERROR_RADIO_INVALID_STATE; } - ret_state = gst_element_get_state (radio->pGstreamer_s->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); + ret_state = gst_element_get_state(radio->pGstreamer_s->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); if (ret_state == GST_STATE_CHANGE_FAILURE) { MMRADIO_LOG_DEBUG("GST_STATE_CHANGE_FAILURE"); - gst_object_unref (radio->pGstreamer_s->pipeline); - g_free (radio->pGstreamer_s); + gst_object_unref(radio->pGstreamer_s->pipeline); + g_free(radio->pGstreamer_s); return MM_ERROR_RADIO_INVALID_STATE; } else { MMRADIO_LOG_DEBUG("[%s][%05d] GST_STATE_NULL ret_state = %d (GST_STATE_CHANGE_SUCCESS)\n", __func__, __LINE__, ret_state); @@ -758,57 +768,56 @@ _mmradio_stop_pipeline(mm_radio_t* radio) } int -_mmradio_destroy_pipeline(mm_radio_t * radio) +_mmradio_destroy_pipeline(mm_radio_t *radio) { int ret = 0; GstStateChangeReturn ret_state; MMRADIO_LOG_FENTER(); - if(gst_element_set_state (radio->pGstreamer_s->pipeline, GST_STATE_NULL) == GST_STATE_CHANGE_FAILURE) { + if (gst_element_set_state(radio->pGstreamer_s->pipeline, GST_STATE_NULL) == GST_STATE_CHANGE_FAILURE) { MMRADIO_LOG_DEBUG("Fail to change pipeline state"); - gst_object_unref (radio->pGstreamer_s->pipeline); - g_free (radio->pGstreamer_s); + gst_object_unref(radio->pGstreamer_s->pipeline); + g_free(radio->pGstreamer_s); return MM_ERROR_RADIO_INVALID_STATE; } - ret_state = gst_element_get_state (radio->pGstreamer_s->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); + ret_state = gst_element_get_state(radio->pGstreamer_s->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); if (ret_state == GST_STATE_CHANGE_FAILURE) { MMRADIO_LOG_DEBUG("GST_STATE_CHANGE_FAILURE"); - gst_object_unref (radio->pGstreamer_s->pipeline); - g_free (radio->pGstreamer_s); + gst_object_unref(radio->pGstreamer_s->pipeline); + g_free(radio->pGstreamer_s); return MM_ERROR_RADIO_INVALID_STATE; } else { MMRADIO_LOG_DEBUG("[%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); + gst_object_unref(radio->pGstreamer_s->pipeline); + g_free(radio->pGstreamer_s); MMRADIO_LOG_FLEAVE(); return ret; } #endif int -_mmradio_seek(mm_radio_t* radio, MMRadioSeekDirectionType direction) +_mmradio_seek(mm_radio_t *radio, MMRadioSeekDirectionType direction) { MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); - MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_SEEK ); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SEEK); - int ret = 0; + int ret = 0; -// if( _mmradio_mute(radio) != MM_ERROR_NONE) -// return MM_ERROR_RADIO_NOT_INITIALIZED; + /* if( _mmradio_mute(radio) != MM_ERROR_NONE) */ + /* return MM_ERROR_RADIO_NOT_INITIALIZED; */ MMRADIO_SLOG_DEBUG("trying to seek. direction[0:UP/1:DOWN) %d\n", direction); radio->seek_direction = direction; ret = pthread_create(&radio->seek_thread, NULL, - (void *)__mmradio_seek_thread, (void *)radio); + (void *)__mmradio_seek_thread, (void *)radio); - if ( ret ) - { + if (ret) { MMRADIO_LOG_DEBUG("failed create thread\n"); return MM_ERROR_RADIO_INTERNAL; } @@ -819,27 +828,26 @@ _mmradio_seek(mm_radio_t* radio, MMRadioSeekDirectionType direction) } int -_mmradio_start_scan(mm_radio_t* radio) +_mmradio_start_scan(mm_radio_t *radio) { MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); - MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_START_SCAN ); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_START_SCAN); int scan_tr_id = 0; radio->stop_scan = false; scan_tr_id = pthread_create(&radio->scan_thread, NULL, - (void *)__mmradio_scan_thread, (void *)radio); + (void *)__mmradio_scan_thread, (void *)radio); - if (scan_tr_id != 0) - { + if (scan_tr_id != 0) { MMRADIO_LOG_DEBUG("failed to create thread : scan\n"); return MM_ERROR_RADIO_NOT_INITIALIZED; } - MMRADIO_SET_STATE( radio, MM_RADIO_STATE_SCANNING ); + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_SCANNING); MMRADIO_LOG_FLEAVE(); @@ -847,23 +855,22 @@ _mmradio_start_scan(mm_radio_t* radio) } int -_mmradio_stop_scan(mm_radio_t* radio) +_mmradio_stop_scan(mm_radio_t *radio) { MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); - MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_STOP_SCAN ); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_STOP_SCAN); radio->stop_scan = true; - if( radio->scan_thread > 0 ) - { + if (radio->scan_thread > 0) { pthread_cancel(radio->scan_thread); pthread_join(radio->scan_thread, NULL); - radio->scan_thread = 0; + radio->scan_thread = 0; } - MMRADIO_SET_STATE( radio, MM_RADIO_STATE_READY ); + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY); MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_STOP, NULL); MMRADIO_LOG_FLEAVE(); @@ -872,16 +879,15 @@ _mmradio_stop_scan(mm_radio_t* radio) } int -_mm_radio_get_signal_strength(mm_radio_t* radio, int *value) +_mm_radio_get_signal_strength(mm_radio_t *radio, int *value) { MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); + MMRADIO_CHECK_INSTANCE(radio); - return_val_if_fail( value, MM_ERROR_INVALID_ARGUMENT ); + return_val_if_fail(value, MM_ERROR_INVALID_ARGUMENT); /* just return stored frequency if radio device is not ready */ - if ( radio->radio_fd < 0 ) - { + if (radio->radio_fd < 0) { MMRADIO_SLOG_DEBUG("Device not ready so sending 0\n"); *value = 0; return MM_ERROR_NONE; @@ -894,25 +900,25 @@ _mm_radio_get_signal_strength(mm_radio_t* radio, int *value) } void -__mmradio_scan_thread(mm_radio_t* radio) +__mmradio_scan_thread(mm_radio_t *radio) { int ret = 0; int prev_freq = 0; EmultatorIdx = 0; + TTRACE_ASYNCBEGIN("MMRADIO:SCAN_THREAD", radio->radio_fd); MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); -// if( _mmradio_mute(radio) != MM_ERROR_NONE) -// goto FINISHED; + MMRADIO_CHECK_INSTANCE(radio); + /* if( _mmradio_mute(radio) != MM_ERROR_NONE) */ + /* goto FINISHED; */ - if( _mmradio_set_frequency(radio, radio->region_setting.band_min) != MM_ERROR_NONE) + if (_mmradio_set_frequency(radio, radio->region_setting.band_min) != MM_ERROR_NONE) goto FINISHED; MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_START, NULL); - MMRADIO_SET_STATE( radio, MM_RADIO_STATE_SCANNING ); + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_SCANNING); - while( ! radio->stop_scan ) - { + while (!radio->stop_scan) { int freq = 0; MMMessageParamType param = {0,}; @@ -920,36 +926,34 @@ __mmradio_scan_thread(mm_radio_t* radio) /* now we can get new frequency from radio device */ - if ( radio->stop_scan ) break; + if (radio->stop_scan) break; { usleep(1000 * 1000); freq = MMRadioEmulatorFreq[EmultatorIdx] ; - MMRADIO_LOG_DEBUG("freq: %d", freq); + MMRADIO_LOG_DEBUG("freq: %d", freq); - if ( freq < prev_freq ) - { + if (freq < prev_freq) { MMRADIO_LOG_DEBUG("scanning wrapped around. stopping scan\n"); break; } - if ( freq == prev_freq) + if (freq == prev_freq) continue; prev_freq = param.radio_scan.frequency = freq; MMRADIO_SLOG_DEBUG("scanning : new frequency : [%d]\n", param.radio_scan.frequency); /* drop if max freq is scanned */ - if ( param.radio_scan.frequency == radio->region_setting.band_max - || param.radio_scan.frequency > radio->region_setting.band_max - || param.radio_scan.frequency < radio->region_setting.band_min) - { + if (param.radio_scan.frequency == radio->region_setting.band_max + || param.radio_scan.frequency > radio->region_setting.band_max + || param.radio_scan.frequency < radio->region_setting.band_min) { MMRADIO_LOG_DEBUG("%d freq is dropping...and stopping scan\n", param.radio_scan.frequency); break; } - if ( radio->stop_scan ) break; // doesn't need to post + if (radio->stop_scan) break; /* doesn't need to post */ MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_INFO, ¶m); EmultatorIdx++; @@ -958,12 +962,12 @@ __mmradio_scan_thread(mm_radio_t* radio) FINISHED: radio->scan_thread = 0; - MMRADIO_SET_STATE( radio, MM_RADIO_STATE_READY ); + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY); - if ( ! radio->stop_scan ) - { + if (!radio->stop_scan) { MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_FINISH, NULL); } + TTRACE_ASYNCEND("MMRADIO:SCAN_THREAD", radio->radio_fd); MMRADIO_LOG_FLEAVE(); @@ -973,13 +977,13 @@ FINISHED: } bool -__is_tunable_frequency(mm_radio_t* radio, int freq) +__is_tunable_frequency(mm_radio_t *radio, int freq) { MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); + 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(); @@ -988,7 +992,7 @@ __is_tunable_frequency(mm_radio_t* radio, int freq) } void -__mmradio_seek_thread(mm_radio_t* radio) +__mmradio_seek_thread(mm_radio_t *radio) { int ret = 0; int freq = 0; @@ -1000,12 +1004,12 @@ __mmradio_seek_thread(mm_radio_t* radio) vs.type = V4L2_TUNER_RADIO; vs.wrap_around = DEFAULT_WRAP_AROUND; + TTRACE_ASYNCBEGIN("MMRADIO:SEEK_THREAD", radio->radio_fd); MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); + MMRADIO_CHECK_INSTANCE(radio); /* check direction */ - switch( radio->seek_direction ) - { + switch (radio->seek_direction) { case MM_RADIO_SEEK_UP: vs.seek_upward = 1; break; @@ -1018,44 +1022,41 @@ __mmradio_seek_thread(mm_radio_t* radio) MMRADIO_LOG_DEBUG("seeking....\n"); - while ( ! seek_stop ) - { + EmultatorIdx = 0; + while (!seek_stop) { /* now we can get new frequency from radio device */ { MMRADIO_LOG_DEBUG("start radio->freq: %d", radio->freq); + int i = 0; - for(i = 0; i < EMULATOR_FREQ_MAX; i++) - if(MMRadioEmulatorFreq[i] == radio->freq) + for (i = 0; i < EMULATOR_FREQ_MAX; i++) + if (MMRadioEmulatorFreq[i] == radio->freq) EmultatorIdx = i; - if(vs.seek_upward == 1){ - if(EmultatorIdx == EMULATOR_FREQ_MAX - 1) EmultatorIdx = -1; + if (vs.seek_upward == 1) { + if (EmultatorIdx == EMULATOR_FREQ_MAX - 1) EmultatorIdx = -1; freq = MMRadioEmulatorFreq[EmultatorIdx + 1]; - } - else{ - if(EmultatorIdx == 0) EmultatorIdx = EMULATOR_FREQ_MAX; + } else { + if (EmultatorIdx == 0) EmultatorIdx = EMULATOR_FREQ_MAX; freq = MMRadioEmulatorFreq[EmultatorIdx - 1]; } radio->freq = freq; - MMRADIO_LOG_DEBUG("radio->freq: %d", radio->freq); + MMRADIO_LOG_DEBUG("radio->freq: %d EmultatorIdx: %d", radio->freq, EmultatorIdx); } MMRADIO_LOG_DEBUG("found frequency\n"); /* if same freq is found, ignore it and search next one. */ - if ( freq == radio->prev_seek_freq ) - { + if (freq == radio->prev_seek_freq) { MMRADIO_LOG_DEBUG("It's same with previous found one. So, trying next one. \n"); continue; } - if ( __is_tunable_frequency(radio, freq) ) // check if it's limit freq or not - { + if (__is_tunable_frequency(radio, freq)) { /* check if it's limit freq or not */ /* now tune to new frequency */ ret = _mmradio_set_frequency(radio, freq); - if ( ret ) - { + if (ret) { MMRADIO_LOG_ERROR("failed to tune to new frequency\n"); goto SEEK_FAILED; } @@ -1067,8 +1068,7 @@ __mmradio_seek_thread(mm_radio_t* radio) */ #if 0 ret = _mmradio_unmute(radio); - if ( ret ) - { + if (ret) { MMRADIO_LOG_ERROR("failed to tune to new frequency\n"); goto SEEK_FAILED; } @@ -1080,7 +1080,7 @@ __mmradio_seek_thread(mm_radio_t* radio) } radio->seek_thread = 0; - + TTRACE_ASYNCEND("MMRADIO:SEEK_THREAD", radio->radio_fd); MMRADIO_LOG_FLEAVE(); pthread_exit(NULL); @@ -1091,18 +1091,18 @@ SEEK_FAILED: param.radio_scan.frequency = -1; MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, ¶m); pthread_exit(NULL); + TTRACE_ASYNCEND("MMRADIO:SEEK_THREAD", radio->radio_fd); return; } static bool -__mmradio_post_message(mm_radio_t* radio, enum MMMessageType msgtype, MMMessageParamType* param) +__mmradio_post_message(mm_radio_t *radio, enum MMMessageType msgtype, MMMessageParamType *param) { - MMRADIO_CHECK_INSTANCE( radio ); + MMRADIO_CHECK_INSTANCE(radio); MMRADIO_LOG_FENTER(); - if ( !radio->msg_cb ) - { + if (!radio->msg_cb) { debug_warning("failed to post a message\n"); return false; } @@ -1117,158 +1117,145 @@ __mmradio_post_message(mm_radio_t* radio, enum MMMessageType msgtype, MMMessageP } static int - __mmradio_check_state(mm_radio_t* radio, MMRadioCommand command) - { - MMRadioStateType radio_state = MM_RADIO_STATE_NUM; +__mmradio_check_state(mm_radio_t *radio, MMRadioCommand command) +{ + MMRadioStateType radio_state = MM_RADIO_STATE_NUM; MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); - - radio_state = __mmradio_get_state( radio ); - - MMRADIO_LOG_DEBUG("incomming command : %d current state : %d\n", command, radio_state); - - switch( command ) - { - case MMRADIO_COMMAND_CREATE: - { - if ( radio_state != 0 ) - goto NO_OP; - } - break; - - case MMRADIO_COMMAND_REALIZE: - { - if ( radio_state == MM_RADIO_STATE_READY || - radio_state == MM_RADIO_STATE_PLAYING || - radio_state == MM_RADIO_STATE_SCANNING ) - goto NO_OP; - - if ( radio_state == 0 ) - goto INVALID_STATE; - } - break; - - case MMRADIO_COMMAND_UNREALIZE: - { - if ( radio_state == MM_RADIO_STATE_NULL ) - goto NO_OP; - - /* we can call unrealize at any higher state */ - } - break; - - case MMRADIO_COMMAND_START: - { - if ( radio_state == MM_RADIO_STATE_PLAYING ) - goto NO_OP; - - if ( radio_state != MM_RADIO_STATE_READY ) - goto INVALID_STATE; - } - break; - - case MMRADIO_COMMAND_STOP: - { - if ( radio_state == MM_RADIO_STATE_READY ) - goto NO_OP; - - if ( radio_state != MM_RADIO_STATE_PLAYING ) - goto INVALID_STATE; - } - break; - - case MMRADIO_COMMAND_START_SCAN: - { - if ( radio_state == MM_RADIO_STATE_SCANNING ) - goto NO_OP; - - if ( radio_state != MM_RADIO_STATE_READY ) - goto INVALID_STATE; - } - break; - - case MMRADIO_COMMAND_STOP_SCAN: - { - if ( radio_state == MM_RADIO_STATE_READY ) - goto NO_OP; - - if ( radio_state != MM_RADIO_STATE_SCANNING ) - goto INVALID_STATE; - } - break; - - case MMRADIO_COMMAND_DESTROY: - case MMRADIO_COMMAND_MUTE: - case MMRADIO_COMMAND_UNMUTE: - case MMRADIO_COMMAND_SET_FREQ: - case MMRADIO_COMMAND_GET_FREQ: - case MMRADIO_COMMAND_SET_REGION: - { - /* we can do it at any state */ - } - break; - - case MMRADIO_COMMAND_SEEK: - { - if ( radio_state != MM_RADIO_STATE_PLAYING ) - goto INVALID_STATE; - } - break; - - case MMRADIO_COMMAND_GET_REGION: - { - if ( radio_state == MM_RADIO_STATE_NULL ) - goto INVALID_STATE; - } - break; + MMRADIO_CHECK_INSTANCE(radio); + + radio_state = __mmradio_get_state(radio); + + MMRADIO_LOG_DEBUG("incomming command : %d current state : %d\n", command, radio_state); + + switch (command) { + case MMRADIO_COMMAND_CREATE: { + if (radio_state != 0) + goto NO_OP; + } + break; + + case MMRADIO_COMMAND_REALIZE: { + if (radio_state == MM_RADIO_STATE_READY || + radio_state == MM_RADIO_STATE_PLAYING || + radio_state == MM_RADIO_STATE_SCANNING) + goto NO_OP; + + if (radio_state == 0) + goto INVALID_STATE; + } + break; + + case MMRADIO_COMMAND_UNREALIZE: { + if (radio_state == MM_RADIO_STATE_NULL) + goto NO_OP; + + /* we can call unrealize at any higher state */ + } + break; + + case MMRADIO_COMMAND_START: { + if (radio_state == MM_RADIO_STATE_PLAYING) + goto NO_OP; - default: - MMRADIO_LOG_DEBUG("not handled in FSM. don't care it\n"); - break; - } + if (radio_state != MM_RADIO_STATE_READY) + goto INVALID_STATE; + } + break; - MMRADIO_LOG_DEBUG("status OK\n"); + case MMRADIO_COMMAND_STOP: { + if (radio_state == MM_RADIO_STATE_READY) + goto NO_OP; + + if (radio_state != MM_RADIO_STATE_PLAYING) + goto INVALID_STATE; + } + break; - radio->cmd = command; + case MMRADIO_COMMAND_START_SCAN: { + if (radio_state == MM_RADIO_STATE_SCANNING) + goto NO_OP; + + if (radio_state != MM_RADIO_STATE_READY) + goto INVALID_STATE; + } + break; + + case MMRADIO_COMMAND_STOP_SCAN: { + if (radio_state == MM_RADIO_STATE_READY) + goto NO_OP; + + if (radio_state != MM_RADIO_STATE_SCANNING) + goto INVALID_STATE; + } + break; + + case MMRADIO_COMMAND_DESTROY: + case MMRADIO_COMMAND_MUTE: + case MMRADIO_COMMAND_UNMUTE: + case MMRADIO_COMMAND_SET_FREQ: + case MMRADIO_COMMAND_GET_FREQ: + case MMRADIO_COMMAND_SET_REGION: { + /* we can do it at any state */ + } + break; + + case MMRADIO_COMMAND_SEEK: { + if (radio_state != MM_RADIO_STATE_PLAYING) + goto INVALID_STATE; + } + break; + + case MMRADIO_COMMAND_GET_REGION: { + if (radio_state == MM_RADIO_STATE_NULL) + goto INVALID_STATE; + } + break; + + default: + MMRADIO_LOG_DEBUG("not handled in FSM. don't care it\n"); + break; + } + + MMRADIO_LOG_DEBUG("status OK\n"); + + radio->cmd = command; MMRADIO_LOG_FLEAVE(); - return MM_ERROR_NONE; + return MM_ERROR_NONE; - INVALID_STATE: - debug_warning("invalid state. current : %d command : %d\n", - radio_state, command); +INVALID_STATE: + debug_warning("invalid state. current : %d command : %d\n", + radio_state, command); MMRADIO_LOG_FLEAVE(); - return MM_ERROR_RADIO_INVALID_STATE; + return MM_ERROR_RADIO_INVALID_STATE; - NO_OP: - debug_warning("mm-radio is in the desired state(%d). doing noting\n", radio_state); +NO_OP: + debug_warning("mm-radio is in the desired state(%d). doing noting\n", radio_state); MMRADIO_LOG_FLEAVE(); - return MM_ERROR_RADIO_NO_OP; + return MM_ERROR_RADIO_NO_OP; - } +} static bool -__mmradio_set_state(mm_radio_t* radio, int new_state) +__mmradio_set_state(mm_radio_t *radio, int new_state) { MMMessageParamType msg = {0, }; int msg_type = MM_MESSAGE_UNKNOWN; MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); + MMRADIO_CHECK_INSTANCE(radio); - if ( ! radio ) - { + if (!radio) { debug_warning("calling set_state with invalid radio handle\n"); return false; } - if ( radio->current_state == new_state && radio->pending_state == 0 ) - { + if (radio->current_state == new_state && radio->pending_state == 0) { debug_warning("we are in same state\n"); return true; } @@ -1282,27 +1269,24 @@ __mmradio_set_state(mm_radio_t* radio, int new_state) msg.state.current = radio->current_state; /* post message to application */ - switch( radio->sm.by_asm_cb ) - { - case MMRADIO_ASM_CB_NONE: - { - msg_type = MM_MESSAGE_STATE_CHANGED; - MMRADIO_POST_MSG( radio, msg_type, &msg ); - } - break; + switch (radio->sm.by_asm_cb) { + case MMRADIO_ASM_CB_NONE: { + msg_type = MM_MESSAGE_STATE_CHANGED; + MMRADIO_POST_MSG(radio, msg_type, &msg); + } + break; - case MMRADIO_ASM_CB_POSTMSG: - { - msg_type = MM_MESSAGE_STATE_INTERRUPTED; - msg.union_type = MM_MSG_UNION_CODE; - msg.code = radio->sm.event_src; - MMRADIO_POST_MSG( radio, msg_type, &msg ); - } - break; + case MMRADIO_ASM_CB_POSTMSG: { + msg_type = MM_MESSAGE_STATE_INTERRUPTED; + msg.union_type = MM_MSG_UNION_CODE; + msg.code = radio->sm.event_src; + MMRADIO_POST_MSG(radio, msg_type, &msg); + } + break; case MMRADIO_ASM_CB_SKIP_POSTMSG: default: - break; + break; } MMRADIO_LOG_FLEAVE(); @@ -1311,20 +1295,20 @@ __mmradio_set_state(mm_radio_t* radio, int new_state) } static int -__mmradio_get_state(mm_radio_t* radio) +__mmradio_get_state(mm_radio_t *radio) { - MMRADIO_CHECK_INSTANCE( radio ); + MMRADIO_CHECK_INSTANCE(radio); MMRADIO_LOG_DEBUG("radio state : current : [%d] old : [%d] pending : [%d]\n", - radio->current_state, radio->old_state, radio->pending_state ); + radio->current_state, radio->old_state, radio->pending_state); return radio->current_state; } - +#ifdef FEATURE_ASM_SUPPORT ASM_cb_result_t -__mmradio_asm_callback(int handle, ASM_event_sources_t event_source, ASM_sound_commands_t command, unsigned int sound_status, void* cb_data) +__mmradio_asm_callback(int handle, ASM_event_sources_t event_source, ASM_sound_commands_t command, unsigned int sound_status, void *cb_data) { - mm_radio_t* radio = (mm_radio_t*) cb_data; + mm_radio_t *radio = (mm_radio_t *) cb_data; int result = MM_ERROR_NONE; ASM_cb_result_t cb_res = ASM_CB_RES_NONE; @@ -1332,78 +1316,161 @@ __mmradio_asm_callback(int handle, ASM_event_sources_t event_source, ASM_sound_c radio->sm.event_src = event_source; - switch(command) - { + switch (command) { case ASM_COMMAND_STOP: - case ASM_COMMAND_PAUSE: - { - MMRADIO_LOG_DEBUG("ASM asked me to stop. cmd : %d\n", command); - switch(event_source) - { - case ASM_EVENT_SOURCE_CALL_START: - case ASM_EVENT_SOURCE_ALARM_START: - case ASM_EVENT_SOURCE_EARJACK_UNPLUG: - case ASM_EVENT_SOURCE_MEDIA: - { - radio->sm.by_asm_cb = MMRADIO_ASM_CB_POSTMSG; - result = _mmradio_stop(radio); - if( result ) - { - MMRADIO_LOG_ERROR("failed to stop radio\n"); - } - - MMRADIO_LOG_DEBUG("skip unrealize in asm callback"); - } - break; - - case ASM_EVENT_SOURCE_RESOURCE_CONFLICT: - default: - { - radio->sm.by_asm_cb = MMRADIO_ASM_CB_POSTMSG; - result = _mmradio_stop(radio); - if( result ) - { - MMRADIO_LOG_ERROR("failed to stop radio\n"); - } + case ASM_COMMAND_PAUSE: { + MMRADIO_LOG_DEBUG("ASM asked me to stop. cmd : %d\n", command); + switch (event_source) { + case ASM_EVENT_SOURCE_CALL_START: + case ASM_EVENT_SOURCE_ALARM_START: + case ASM_EVENT_SOURCE_EARJACK_UNPLUG: + case ASM_EVENT_SOURCE_MEDIA: { + radio->sm.by_asm_cb = MMRADIO_ASM_CB_POSTMSG; + result = _mmradio_stop(radio); + if (result) { + MMRADIO_LOG_ERROR("failed to stop radio\n"); + } + + MMRADIO_LOG_DEBUG("skip unrealize in asm callback"); + } + break; + + case ASM_EVENT_SOURCE_RESOURCE_CONFLICT: + default: { + radio->sm.by_asm_cb = MMRADIO_ASM_CB_POSTMSG; + result = _mmradio_stop(radio); + if (result) { + MMRADIO_LOG_ERROR("failed to stop radio\n"); + } + } + break; } - break; + cb_res = ASM_CB_RES_STOP; } - cb_res = ASM_CB_RES_STOP; - } - break; + break; case ASM_COMMAND_PLAY: - case ASM_COMMAND_RESUME: - { - MMMessageParamType msg = {0,}; - msg.union_type = MM_MSG_UNION_CODE; - msg.code = event_source; + case ASM_COMMAND_RESUME: { + MMMessageParamType msg = {0,}; + msg.union_type = MM_MSG_UNION_CODE; + msg.code = event_source; - MMRADIO_LOG_DEBUG("Got ASM resume message by %d\n", msg.code); - MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg); + MMRADIO_LOG_DEBUG("Got ASM resume message by %d\n", msg.code); + MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg); - cb_res = ASM_CB_RES_IGNORE; - radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE; - } - break; + cb_res = ASM_CB_RES_IGNORE; + radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE; + } + break; default: - break; + break; } MMRADIO_LOG_FLEAVE(); return cb_res; } +#else +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, + const char *additional_info, void *user_data) +{ + mm_radio_t *radio = (mm_radio_t *) user_data; + ASM_event_sources_t event_source; + int result = MM_ERROR_NONE; + int postMsg = false; -int -_mmradio_get_region_type(mm_radio_t*radio, MMRadioRegionType *type) + MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_INSTANCE(radio); + + mmradio_get_audio_focus_reason(focus_state, reason_for_change, &event_source, &postMsg); + radio->sm.event_src = event_source; + + switch (focus_state) { + case FOCUS_IS_RELEASED: + radio->sm.by_asm_cb = MMRADIO_ASM_CB_POSTMSG; + result = _mmradio_stop(radio); + if (result) { + MMRADIO_LOG_ERROR("failed to stop radio\n"); + } + MMRADIO_LOG_DEBUG("FOCUS_IS_RELEASED\n"); + break; + + case FOCUS_IS_ACQUIRED: { + MMMessageParamType msg = {0,}; + msg.union_type = MM_MSG_UNION_CODE; + msg.code = event_source; + if (postMsg) + MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg); + + radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE; + + MMRADIO_LOG_DEBUG("FOCUS_IS_ACQUIRED\n"); + } + break; + + default: + MMRADIO_LOG_DEBUG("Unknown focus_state\n"); + break; + } + MMRADIO_LOG_FLEAVE(); +} + +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; + ASM_event_sources_t event_source; + int result = MM_ERROR_NONE; + int postMsg = false; + + MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_INSTANCE(radio); + + mmradio_get_audio_focus_reason(!focus_state, reason_for_change, &event_source, &postMsg); + radio->sm.event_src = event_source; + + switch (focus_state) { + case FOCUS_IS_RELEASED: { + MMMessageParamType msg = {0,}; + msg.union_type = MM_MSG_UNION_CODE; + msg.code = event_source; + if (postMsg) + MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg); + + radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE; + + MMRADIO_LOG_DEBUG("FOCUS_IS_ACQUIRED postMsg: %d\n", postMsg); + } + break; + + case FOCUS_IS_ACQUIRED: { + radio->sm.by_asm_cb = MMRADIO_ASM_CB_POSTMSG; + result = _mmradio_stop(radio); + if (result) { + MMRADIO_LOG_ERROR("failed to stop radio\n"); + } + MMRADIO_LOG_DEBUG("FOCUS_IS_RELEASED\n"); + break; + } + break; + + default: + MMRADIO_LOG_DEBUG("Unknown focus_state postMsg : %d\n", postMsg); + break; + } + MMRADIO_LOG_FLEAVE(); +} +#endif + +int _mmradio_get_region_type(mm_radio_t *radio, MMRadioRegionType *type) { MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); - MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_GET_REGION ); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION); - return_val_if_fail( type, MM_ERROR_INVALID_ARGUMENT ); + return_val_if_fail(type, MM_ERROR_INVALID_ARGUMENT); *type = radio->region_setting.country; @@ -1411,14 +1478,13 @@ _mmradio_get_region_type(mm_radio_t*radio, MMRadioRegionType *type) return MM_ERROR_NONE; } -int -_mmradio_get_region_frequency_range(mm_radio_t* radio, unsigned int *min_freq, unsigned int *max_freq) +int _mmradio_get_region_frequency_range(mm_radio_t *radio, unsigned int *min_freq, unsigned int *max_freq) { MMRADIO_LOG_FENTER(); - MMRADIO_CHECK_INSTANCE( radio ); - MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_GET_REGION ); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION); - return_val_if_fail( min_freq && max_freq, MM_ERROR_INVALID_ARGUMENT ); + return_val_if_fail(min_freq && max_freq, MM_ERROR_INVALID_ARGUMENT); *min_freq = radio->region_setting.band_min; *max_freq = radio->region_setting.band_max; @@ -1427,35 +1493,50 @@ _mmradio_get_region_frequency_range(mm_radio_t* radio, unsigned int *min_freq, u return MM_ERROR_NONE; } +int _mmradio_get_channel_spacing(mm_radio_t *radio, unsigned int *ch_spacing) +{ + MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION); + + return_val_if_fail(ch_spacing, MM_ERROR_INVALID_ARGUMENT); + + *ch_spacing = radio->region_setting.channel_spacing; + + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_NONE; +} + + static int __mmradio_get_wave_num(mm_radio_t *radio) { int val = 0; MMRADIO_LOG_FENTER(); - switch(radio->freq){ - case 89100: - val = 1; - break; - - case 89900: - val = 5; - break; - - case 91900: - val = 6; - break; - - case 99900: - val = 8; - break; - - case 107700: - val = 9; - break; - - default : - val = 9; - break; + switch (radio->freq) { + case 89100: + val = 1; + break; + + case 89900: + val = 5; + break; + + case 91900: + val = 6; + break; + + case 99900: + val = 8; + break; + + case 107700: + val = 9; + break; + + default: + val = 9; + break; } MMRADIO_LOG_DEBUG("freq: %d, val : %d", radio->freq, val); MMRADIO_LOG_FLEAVE(); diff --git a/src/mm_radio_priv_sprd.c b/src/mm_radio_priv_sprd.c new file mode 100755 index 0000000..2bb5c7f --- /dev/null +++ b/src/mm_radio_priv_sprd.c @@ -0,0 +1,3081 @@ +/* + * libmm-radio + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: JongHyuk Choi , YoungHwan An + * + * 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 FILES | +| | +========================================================================================== */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + + +#include "mm_radio_priv_common.h" +#include "mm_radio_priv_v4l2.h" + +#define MM_RADIO_EAR_PHONE_POLICY +#define ENABLE_FM_TUNING + +//#ifdef USE_FM_RADIO_V4L2_VOLUME /* in sprd sc2331, volume set is handled by mixer to separate rec volume */ + +/*=========================================================================================== +note: This File is specific to fm devices based on v4l2 +============================================================================================*/ + +/*=========================================================================================== + LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE +========================================================================================== */ +/*--------------------------------------------------------------------------- + GLOBAL CONSTANT DEFINITIONS: +---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + IMPORTED VARIABLE DECLARATIONS: +---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + IMPORTED FUNCTION DECLARATIONS: +---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + LOCAL #defines: +---------------------------------------------------------------------------*/ +#define DEFAULT_DEVICE "/dev/radio0" +#define TUNER_INDEX 0 + +#define DEFAULT_FREQ 107700 +#define SPRD_DEFAULT_FREQ 99900 + +#define FREQ_FRAC 16 +#define RADIO_FREQ_FORMAT_SET(x_freq) ((x_freq) * FREQ_FRAC) +#define RADIO_FREQ_FORMAT_GET(x_freq) ((x_freq) / FREQ_FRAC) +#define DEFAULT_WRAP_AROUND 1 /*If non-zero, wrap around when at the end of the frequency range, else stop seeking */ + +#define RADIO_DEFAULT_REGION MM_RADIO_REGION_GROUP_EUROPE + +#ifdef USE_FM_RADIO_V4L2_VOLUME +#define FM_VOLUME_BASE 30 +#define FM_VOLUME_MAX 16 +static int fm_volume_tbl[FM_VOLUME_MAX] = { + 0, 2, 4, 8, 15, 30, 45, 70, 80, 100, 125, 150, 180, 210, 230, 255 +}; +#endif + +#define BT_ENABLE "/var/run/bluetooth/bt" +#define DEVICE_CLOSE_RETRY_CNT 10 +#define HCI_DISABLE_RETRY_CNT 100 + +/*--------------------------------------------------------------------------- + LOCAL CONSTANT DEFINITIONS: +---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + LOCAL DATA TYPE DEFINITIONS: +---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + GLOBAL VARIABLE DEFINITIONS: +---------------------------------------------------------------------------*/ +extern int errno; + +/*--------------------------------------------------------------------------- + LOCAL VARIABLE DEFINITIONS: +---------------------------------------------------------------------------*/ +/* radio region configuration table */ +static const MMRadioRegion_t region_table[] = { + { /* Notrh America, South America, South Korea, Taiwan, Australia */ + MM_RADIO_REGION_GROUP_USA, /* region type */ + MM_RADIO_DEEMPHASIS_75_US, /* de-emphasis */ + MM_RADIO_FREQ_MIN_87500_KHZ, /* min freq. */ + MM_RADIO_FREQ_MAX_108000_KHZ, /* max freq. */ + 50, + }, + { /* China, Europe, Africa, Middle East, Hong Kong, India, Indonesia, Russia, Singapore */ + MM_RADIO_REGION_GROUP_EUROPE, + MM_RADIO_DEEMPHASIS_50_US, + MM_RADIO_FREQ_MIN_87500_KHZ, + MM_RADIO_FREQ_MAX_108000_KHZ, + 50, + }, + { + MM_RADIO_REGION_GROUP_JAPAN, + MM_RADIO_DEEMPHASIS_50_US, + MM_RADIO_FREQ_MIN_76100_KHZ, + MM_RADIO_FREQ_MAX_89900_KHZ, + 50, + }, +}; +/*--------------------------------------------------------------------------- + LOCAL FUNCTION PROTOTYPES: +---------------------------------------------------------------------------*/ +static bool __mmradio_post_message(mm_radio_t *radio, enum MMMessageType msgtype, MMMessageParamType *param); +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); +static void __mmradio_seek_thread(mm_radio_t *radio); +static void __mmradio_scan_thread(mm_radio_t *radio); +#ifdef FEATURE_ASM_SUPPORT +static ASM_cb_result_t __mmradio_asm_callback(int handle, ASM_event_sources_t sound_event, ASM_sound_commands_t command, unsigned int sound_status, void *cb_data); +#else +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, const char *additional_info, void *user_data); +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 +static bool __is_tunable_frequency(mm_radio_t *radio, int freq); +static int __mmradio_set_band_range(mm_radio_t *radio); +#ifdef USE_FM_RADIO_V4L2_VOLUME +static void __mmradio_volume_change_cb(volume_type_t type, unsigned int volume, void *user_data); +static int __mmradio_set_volume(mm_radio_t *radio, unsigned int value); +static int __mmradio_get_volume(mm_radio_t *radio, unsigned int *value); +static void __mmradio_active_device_changed_cb (mm_sound_device_in device_in, mm_sound_device_out device_out, void *user_data); +#endif +static int __mmradio_enable_bluetooth(mm_radio_t *radio, int enable); +static int __mmradio_wait_bluetooth_ready(mm_radio_t *radio, int wait_active, int retry_count); + +void __mm_radio_init_tuning_params(mm_radio_t *radio); +void __mm_radio_apply_tuning_params(mm_radio_t *radio); + +static int __mmradio_init_v4l2_device(mm_radio_t *radio); +static void __mmradio_deinit_v4l2_device(mm_radio_t *radio); +static int __mm_radio_rds_callback(int type, void *data, void *user_data); +int _mmradio_pause(mm_radio_t *radio); +#ifdef USE_FM_RADIO_V4L2_VOLUME +static void _mmradio_fadevolume_cancel(mm_radio_t *radio); +static int _mm_radio_recording_volume_change_policy(mm_radio_t *radio, int present_volume); +#endif +static void __mmradio_event_thread(mm_radio_t *radio); + +/*=========================================================================== + 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 + *---------------------------------------------------------------------------*/ +int _mmradio_apply_region(mm_radio_t *radio, MMRadioRegionType region, bool update) +{ + int count = 0; + int index = 0; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_REGION); + + /* if needed, radio region must be updated. + * Otherwise, just applying settings to device without it. + */ + if (update) { + count = ARRAY_SIZE(region_table); + + /*TODO: if auto is supported...get the region info. here */ + + /* update radio region settings */ + for (index = 0; index < count; index++) { + /* find the region from pre-defined table*/ + if (region_table[index].country == region) { + radio->region_setting.country = region_table[index].country; + radio->region_setting.deemphasis = region_table[index].deemphasis; + radio->region_setting.band_min = region_table[index].band_min; + radio->region_setting.band_max = region_table[index].band_max; + radio->region_setting.channel_spacing = region_table[index].channel_spacing; + } + } + } + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; +} + +int _mmradio_prepare_device(mm_radio_t *radio) +{ + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_INSTANCE(radio); + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE(priv_sprd_v4l2); + + if (!priv_sprd_v4l2->device_ready) { + /*Only check blue-tooth - As this is not a reference count we need not care about the number of calls to enable */ + if (MM_ERROR_NONE != __mmradio_enable_bluetooth(radio, MM_RADIO_TRUE)) { + MMRADIO_LOG_ERROR("__mmradio_enable_bluetooth is failed\n"); + return MM_ERROR_RADIO_DEVICE_NOT_OPENED; + } + + if (MM_ERROR_NONE != __mmradio_wait_bluetooth_ready(radio, MM_RADIO_TRUE, 50)) { + MMRADIO_LOG_ERROR("__mmradio_wait_bluetooth_ready is failed\n"); + return MM_ERROR_RADIO_DEVICE_NOT_OPENED; + } + } else { + MMRADIO_LOG_INFO("HCI attach is already started"); + } + priv_sprd_v4l2->device_ready = MM_RADIO_TRUE; + + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_NONE; +} + +void _mmradio_unprepare_device(mm_radio_t *radio) +{ + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio); + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE_RETURN_VOID(priv_sprd_v4l2); + + /*This is done locked here becuase pause and stop doesn't contain unprepare and is handeled seperatly*/ + pthread_mutex_lock(&radio->state_mutex); + + if (radio->radio_fd < 0) { + if (priv_sprd_v4l2->device_ready) { + MMRADIO_LOG_INFO("try to __mmradio_enable_bluetooth (disable)\n"); + if (MM_ERROR_NONE != __mmradio_enable_bluetooth(radio, FALSE)) { + MMRADIO_LOG_ERROR("__mmradio_enable_bluetooth (disable) is failed\n"); + } else { + /* FIXME: if there is /var/run/bluetooth/bt, BT is enabled. */ + int bt_disabled = 0; + int try_cnt = 0; +bt_check_again: + bt_disabled = access(BT_ENABLE, F_OK); + if (bt_disabled == 0) { + MMRADIO_LOG_INFO("BT is enabled. we will not wait hci disable."); + /* FIXME: we should add some logic for waiting FM close itself later */ + } else { + int ret = MM_ERROR_NONE; + /* fopen BT failed. it means that we should wait hci attach disabled completely */ + MMRADIO_LOG_DEBUG("BT disabled. (%s:%d). Try to disable hci attach", strerror(errno), errno); + ret = __mmradio_wait_bluetooth_ready(radio, MM_RADIO_FALSE, 1); + if (ret == MM_ERROR_RADIO_INVALID_STATE) { + try_cnt++; + if (try_cnt <= HCI_DISABLE_RETRY_CNT) { + MMRADIO_LOG_INFO("still hci attach is Active. Try again (%d/%d)", try_cnt, HCI_DISABLE_RETRY_CNT); + goto bt_check_again; + } + } + } + usleep(200 * 1000); /* FIXME: sleep 200 ms for waiting hci disable in broadcom */ + MMRADIO_LOG_INFO("__mmradio_enable_bluetooth (disable) is success\n"); + } + priv_sprd_v4l2->device_ready = MM_RADIO_FALSE; + } else { + MMRADIO_LOG_INFO("HCI attach is already stopped"); + } + } else { + MMRADIO_LOG_WARNING("radio_fd(%d) still opened. can not disable bluetooth now", radio->radio_fd); + } + + pthread_mutex_unlock(&radio->state_mutex); +} + +int _mmradio_create_radio(mm_radio_t *radio) +{ + int ret = 0; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_CREATE); + + /* set default value */ + radio->radio_fd = -1; + radio->freq = DEFAULT_FREQ; + + memset(&radio->region_setting, 0, sizeof(MMRadioRegion_t)); + + /*allocate memory for chipset specific attributes*/ + radio->vender_specific_handle = (MMRadioVenderHandle) malloc(sizeof(mm_radio_priv_v4l2_t)); + if (!radio->vender_specific_handle) { + MMRADIO_LOG_CRITICAL("cannot allocate memory for mm_radio_priv_sprd_t\n"); + return MM_ERROR_RADIO_NO_FREE_SPACE; + } + memset(radio->vender_specific_handle, 0, sizeof(mm_radio_priv_v4l2_t)); + + /* create command lock */ + ret = pthread_mutex_init(&radio->cmd_lock, NULL); + if (ret) { + MMRADIO_LOG_ERROR("mutex creation failed\n"); + return MM_ERROR_RADIO_INTERNAL; + } + + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_NULL); + +#ifdef FEATURE_ASM_SUPPORT + /* register to ASM */ + ret = mmradio_asm_register(&radio->sm, __mmradio_asm_callback, (void *)radio); +#else + ret = mmradio_audio_focus_register(&radio->sm, _mmradio_sound_focus_cb, (void *)radio); +#endif + if (ret) { + /* NOTE : we are dealing it as an error since we cannot expect it's behavior */ + MMRADIO_LOG_ERROR("failed to register asm server\n"); + return MM_ERROR_RADIO_INTERNAL; + } + radio->event_queue = g_async_queue_new(); + if (!radio->event_queue) { + MMRADIO_LOG_ERROR("failed to get g_async_queue_new \n"); + return MM_ERROR_RADIO_INTERNAL; + } + + ret = pthread_create(&radio->event_thread, NULL, (void *)__mmradio_event_thread, (void *)radio); + if (ret) { + /* NOTE : we are dealing it as an error since we cannot expect it's behavior */ + MMRADIO_LOG_ERROR("failed to register asm server\n"); + return MM_ERROR_RADIO_INTERNAL; + } + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; +} + +int __mmradio_init_v4l2_device(mm_radio_t *radio) +{ + int ret = MM_ERROR_NONE; + int try_count = DEV_OPEN_RETRY_COUNT; + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE(priv_sprd_v4l2); + /* open radio device */ + if (radio->radio_fd < 0) { + MMRadioRegionType region = MM_RADIO_REGION_GROUP_NONE; + bool update = MM_RADIO_FALSE; +try_again: + /* open device */ + radio->radio_fd = open(DEFAULT_DEVICE, O_RDONLY | O_CLOEXEC); + if (radio->radio_fd < 0) { + MMRADIO_LOG_ERROR("failed to open radio device[%s] because of %s(%d)\n", + DEFAULT_DEVICE, strerror(errno), errno); + /* check error */ + switch (errno) { + case ENOENT: + ret = MM_ERROR_RADIO_DEVICE_NOT_FOUND; + goto error; + case EACCES: + ret = MM_ERROR_RADIO_PERMISSION_DENIED; + goto error; + case EBUSY: + ret = MM_ERROR_RADIO_DEVICE_NOT_OPENED; + goto error; + case EAGAIN: + if (try_count > 0) { + try_count--; + MMRADIO_LOG_ERROR("Kernel asked me to try again!!! lets try %d more time(s)", try_count); + /*we make device as not ready because if it was we would not get here*/ + priv_sprd_v4l2->device_ready = MM_RADIO_FALSE; + ret = _mmradio_prepare_device(radio); + if (ret) { + MMRADIO_LOG_ERROR("Coundn't prepare the device - 0x%x\n", ret); + goto error; + } + goto try_again; + } else { + MMRADIO_LOG_ERROR("Out of luck!! we return MM_ERROR_RADIO_DEVICE_NOT_OPENED error"); + ret = MM_ERROR_RADIO_DEVICE_NOT_OPENED; + goto error; + } + default: + ret = MM_ERROR_RADIO_DEVICE_NOT_OPENED; + goto error; + } + } + MMRADIO_LOG_DEBUG("radio device fd = %d\n", radio->radio_fd); + + /* query radio device capabilities. */ + if (ioctl(radio->radio_fd, VIDIOC_QUERYCAP, &(priv_sprd_v4l2->vc)) < 0) { + MMRADIO_LOG_ERROR("VIDIOC_QUERYCAP failed!%s\n", strerror(errno)); + goto error; + } + + if (!(priv_sprd_v4l2->vc.capabilities & V4L2_CAP_TUNER)) { + MMRADIO_LOG_ERROR("this system can't support fm-radio!\n"); + goto error; + } + + /* set tuner audio mode */ + ret = ioctl(radio->radio_fd, VIDIOC_G_TUNER, &(priv_sprd_v4l2->vt)); + if (ret < 0) { + MMRADIO_LOG_ERROR("VIDIOC_G_TUNER failed with %s", strerror(errno)); + goto error; + } + + if (!((priv_sprd_v4l2->vt).capability & V4L2_TUNER_CAP_STEREO)) { + MMRADIO_LOG_ERROR("this system can support mono!\n"); + (priv_sprd_v4l2->vt).audmode = V4L2_TUNER_MODE_MONO; + } else { + (priv_sprd_v4l2->vt).audmode = V4L2_TUNER_MODE_STEREO; + } + + /* set tuner index. Must be 0. */ + (priv_sprd_v4l2->vt).index = TUNER_INDEX; + ret = ioctl(radio->radio_fd, VIDIOC_S_TUNER, &(priv_sprd_v4l2->vt)); + if (ret < 0) { + MMRADIO_LOG_ERROR("VIDIOC_S_TUNER failed with %s", strerror(errno)); + goto error; + } + + + 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 band range to device */ + ret = __mmradio_set_band_range(radio); + MMRADIO_CHECK_GOTO_IF_FAIL(ret, "set band range", error); + } + + return ret; +error: + __mmradio_deinit_v4l2_device(radio); + return ret; +} + +void __mmradio_deinit_v4l2_device(mm_radio_t *radio) +{ + int ret = MM_ERROR_NONE; + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio); + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE_RETURN_VOID(priv_sprd_v4l2); + + /*don't let any other ioctl in other threads*/ + pthread_mutex_lock(&radio->volume_lock); + + /* close radio device here !!!! */ + if (radio->radio_fd >= 0) { + MMRADIO_LOG_INFO("try to close Device"); + ret = close(radio->radio_fd); + if (ret < 0) { + MMRADIO_LOG_ERROR("failed to close radio device[%s] because of %s(%d)\n", + DEFAULT_DEVICE, strerror(errno), errno); + } else { + /* FIXME: if there is sys fs, the device is NOT really closed. */ + + FILE *close_check_file = 0; + int try_cnt = 0; + int status = -1; + +close_check_again: + close_check_file = fopen(FMRX_DEVICE_STATUS, "r"); + if (close_check_file) { + try_cnt++; + fscanf(close_check_file, "%d", &status); + fclose(close_check_file); + close_check_file = NULL; + if (status == 1) { /* device is still opened */ + MMRADIO_LOG_INFO("fmrx_status: %d. device is not closed completely. try again (%d/%d)", status, try_cnt, DEVICE_CLOSE_RETRY_CNT); + if (try_cnt <= DEVICE_CLOSE_RETRY_CNT) { + usleep(100 * 1000); /* FIXME: sleep 100 ms for waiting status changing by FM Radio drv */ + goto close_check_again; + } else { + MMRADIO_LOG_ERROR("timeout: fail to close FM Radio device"); + } + } else if (status == 0) { /* device is closed */ + MMRADIO_LOG_INFO("Device closed successfully"); + } else { /* error case with wrong value */ + MMRADIO_LOG_ERROR("Wrong fmrx_status : %d", status); + } + } else { + MMRADIO_LOG_ERROR("can not open %s (%s:%d)", FMRX_DEVICE_STATUS, strerror(errno), errno); + } + } + radio->radio_fd = -1; + } + + /*remove don't let any other ioctl in other threads*/ + pthread_mutex_unlock(&radio->volume_lock); + + MMRADIO_LOG_FLEAVE(); +} + +int _mmradio_realize(mm_radio_t *radio) +{ + int ret = MM_ERROR_NONE; + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + MMRadioRegionType region = MM_RADIO_REGION_GROUP_EUROPE; + bool update = MM_RADIO_TRUE; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_REALIZE); + +#ifdef USE_FM_RADIO_V4L2_VOLUME + /* we will set recording 5-11 */ + radio->radio_tuning.recording_volume_lower_thres = RECORDING_VOLUME_LOWER_THRESHOLD; + radio->radio_tuning.recording_volume_heigher_thres = RECORDING_VOLUME_HEIGHER_THRESHOLD; +#endif + + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE(priv_sprd_v4l2); + + ret = pthread_mutex_init(&radio->volume_lock, NULL); + +#ifdef USE_FM_RADIO_V4L2_VOLUME + /* add volume changed call back */ + MMRADIO_LOG_DEBUG("add mm_sound_add_volume_changed_callback"); + + mm_sound_add_volume_changed_callback(__mmradio_volume_change_cb, (void *)radio); + /* FIXME: for checking device is changed. This can be removed with another solution from sound-server */ + /* add active deviced changed callback */ + MMRADIO_LOG_DEBUG("add mm_sound_add_active_device_changed_callback"); + mm_sound_add_active_device_changed_callback(MM_RADIO_NAME, __mmradio_active_device_changed_cb, (void *)radio); +#endif + + /*we have to load the volume tables in libmmradio only for broadcom?? + */ + int number_of_steps = 0; + int index = 0; + int *table = NULL; + +#ifdef USE_FM_RADIO_V4L2_VOLUME + _mm_radio_load_volume_table(&table, &number_of_steps); + if (table) { + MMRADIO_LOG_DEBUG("number of steps -> %d", number_of_steps); + /*copy from temp structure to main strcture*/ + for (index = 0; index < number_of_steps; index++) { + fm_volume_tbl[index] = table[index]; + } + free(table); + table = NULL; + } +#endif + + /*TODO: double check*/ + priv_sprd_v4l2->device_ready = MM_RADIO_FALSE; + + + /*seek cancel*/ + ret = pthread_mutex_init(&radio->state_mutex, NULL); + if (ret < 0) { + MMRADIO_LOG_DEBUG("Mutex creation failed %d", ret); + } + + /*seek cancel*/ + ret = pthread_mutex_init(&priv_sprd_v4l2->seek_cancel_mutex, NULL); + if (ret < 0) { + MMRADIO_LOG_DEBUG("Mutex creation failed %d", ret); + } + + MMRADIO_LOG_ERROR("_mmradio_realize_pipeline radio->region_setting.country : %d\n", radio->region_setting.country); + /*Init Region settings*/ + /* 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 = MM_RADIO_TRUE; + } else {/* already initialized by application */ + region = radio->region_setting.country; + } + ret = _mmradio_apply_region(radio, region, update); + MMRADIO_CHECK_RETURN_IF_FAIL(ret, "set apply region"); +#ifdef USE_GST_PIPELINE + ret = _mmradio_realize_pipeline(radio); + if (ret) { + MMRADIO_LOG_ERROR("_mmradio_realize_pipeline is failed\n"); + return ret; + } +#endif + radio->is_muted = MM_RADIO_FALSE; + + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY); + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_NONE; +} + +int _mmradio_unrealize(mm_radio_t *radio) +{ + int ret = MM_ERROR_NONE; + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_UNREALIZE); + + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE(priv_sprd_v4l2); + + /*Finish if there are scans*/ + _mmradio_stop_scan(radio); + /*Stop radio if started*/ + _mmradio_stop(radio); + + + /*If applicaiton hasn't called unpreapre let us prepare*/ + _mmradio_unprepare_device(radio); + MMRADIO_LOG_INFO("device Unprep done"); + +#ifdef USE_FM_RADIO_V4L2_VOLUME + mm_sound_remove_volume_changed_callback(); + mm_sound_remove_active_device_changed_callback(MM_RADIO_NAME); +#endif + + pthread_mutex_destroy(&radio->volume_lock); + pthread_mutex_destroy(&priv_sprd_v4l2->seek_cancel_mutex); + pthread_mutex_destroy(&radio->state_mutex); + + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_NULL); +#ifndef FEATURE_ASM_SUPPORT + ret = mmradio_set_audio_focus(&radio->sm, _mmradio_sound_focus_watch_cb, FALSE, (void *)radio); +#endif +#ifdef USE_GST_PIPELINE + ret = _mmradio_destroy_pipeline(radio); + if (ret) { + MMRADIO_LOG_ERROR("_mmradio_destroy_pipeline is failed\n"); + return ret; + } +#endif + MMRADIO_LOG_FLEAVE(); + return ret; +} + +int _mmradio_destroy(mm_radio_t *radio) +{ + int ret = MM_ERROR_NONE; + mm_radio_priv_v4l2_t *priv_v4l2_handle = NULL; + + MMRADIO_LOG_INFO(""); + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_DESTROY); + + _mmradio_unrealize(radio); + +#ifdef FEATURE_ASM_SUPPORT + ret = mmradio_asm_deregister(&radio->sm); +#else + ret = mmradio_audio_focus_deregister(&radio->sm); +#endif + if (ret) { + MMRADIO_LOG_ERROR("failed to deregister asm server\n"); + return MM_ERROR_RADIO_INTERNAL; + } + + priv_v4l2_handle = (mm_radio_priv_v4l2_t *)radio->vender_specific_handle; + if (priv_v4l2_handle) { + free(priv_v4l2_handle); + radio->vender_specific_handle = NULL; + } + _mm_radio_event_s *event = g_slice_new0(_mm_radio_event_s); + + if (event == NULL) + return MM_ERROR_RADIO_INTERNAL; + + event->event_type = MMRADIO_EVENT_DESTROY; + + g_async_queue_push_sorted(radio->event_queue, event, event_comparator, NULL); + pthread_join(radio->event_thread, NULL); + + /*Clean up frequency related variables*/ + g_async_queue_unref(radio->event_queue); + + MMRADIO_LOG_INFO(""); + + return ret; +} + +void __mmradio_event_thread(mm_radio_t *radio) +{ + int ret = MM_ERROR_NONE; + MMMessageParamType param = {0,}; + _mm_radio_event_s *event = NULL; + int exit_event_thread = 0; + + /*we run a while one loop*/ + while (exit_event_thread == 0) { + event = (_mm_radio_event_s *)g_async_queue_pop(radio->event_queue); + if (event == NULL) { + MMRADIO_LOG_ERROR("poped message is NULL!"); + goto exit; + } + + /*Its okay to use the command because they are nicely sorted for our needs + * also frequency is way above the needs of our commands simple and less complicated*/ + switch (event->event_type) { + case MMRADIO_EVENT_DESTROY: + MMRADIO_LOG_INFO("get destroy event. pop all event to finish this thread"); + while ((event = (_mm_radio_event_s *)g_async_queue_try_pop(radio->event_queue))) { + if (event != NULL) { + MMRADIO_LOG_DEBUG("drop this msg type: %d", event->event_type); + g_slice_free(_mm_radio_event_s, event); + } + } + exit_event_thread = 1; + break; + + case MMRADIO_EVENT_STOP: + MMRADIO_LOG_INFO("async close device is requested"); + /*we don't clear the frequency here, this might create a problem + * setting frequency after stop??*/ + pthread_mutex_lock(&radio->state_mutex); + __mmradio_deinit_v4l2_device(radio); + pthread_mutex_unlock(&radio->state_mutex); + _mmradio_unprepare_device(radio); + break; + + case MMRADIO_EVENT_SET_FREQ_ASYNC: + MMRADIO_LOG_INFO("processing frequency: %d", event->event_data); + /*we try to call mm_radio api here this is done on purpose, to make sure that cmd lock is held*/ + ret = mm_radio_set_frequency(radio, event->event_data); + if (ret == MM_ERROR_NONE) { + param.radio_scan.frequency = event->event_data; + } else { + param.radio_scan.frequency = ret; /* FIMXE: we need this? */ + } + MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SET_FREQUENCY, ¶m); + break; + + default: + MMRADIO_LOG_ERROR("wrong event_type: %d", event->event_data); + break; + } + } + +exit: + if (event) { + g_slice_free(_mm_radio_event_s, event); + } + MMRADIO_LOG_INFO("event thread is finished"); +} + +int _mmradio_set_frequency_async(mm_radio_t *radio, int freq) +{ + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_FREQ); + + /* check frequency range */ + if (freq < radio->region_setting.band_min + || freq > radio->region_setting.band_max) { + MMRADIO_LOG_ERROR("out of frequency range - %d\n", freq); + return MM_ERROR_INVALID_ARGUMENT; + } + + _mm_radio_event_s *event = g_slice_new0(_mm_radio_event_s); + + if (event == NULL) + return MM_ERROR_RADIO_INTERNAL; + + event->event_type = MMRADIO_EVENT_SET_FREQ_ASYNC; + event->event_data = freq; + + g_async_queue_push(radio->event_queue, event); + + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_NONE; +} + +int _mmradio_set_frequency(mm_radio_t *radio, int freq) /* unit should be KHz */ +{ + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + int ret = 0; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_FREQ); + + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE(priv_sprd_v4l2); + + /* check frequency range */ + if (freq < radio->region_setting.band_min + || freq > radio->region_setting.band_max) { + MMRADIO_LOG_ERROR("out of frequency range - %d\n", freq); + return MM_ERROR_INVALID_ARGUMENT; + } + + if (radio->radio_fd < 0) { + radio->freq = freq; + if (radio->freq == MM_RADIO_FREQ_MIN_87500_KHZ && radio->region_setting.band_min == MM_RADIO_FREQ_MIN_87500_KHZ) + radio->freq = SPRD_DEFAULT_FREQ; + MMRADIO_LOG_WARNING("radio device is not opened to set (%d)! retun ok.", freq); + return MM_ERROR_NONE; + } else { + + /* set it */ + (priv_sprd_v4l2->vf).tuner = 0; + (priv_sprd_v4l2->vf).type = V4L2_TUNER_RADIO; /* if we do not set type, we will get EINVAL */ + (priv_sprd_v4l2->vf).frequency = RADIO_FREQ_FORMAT_SET(freq); + + MMRADIO_LOG_DEBUG("Setting %d frequency\n", freq); + + ret = ioctl(radio->radio_fd, VIDIOC_S_FREQUENCY, &(priv_sprd_v4l2->vf)) ; + if (ret < 0) { + MMRADIO_LOG_ERROR("VIDIOC_S_FREQUENCY failed with %s", strerror(errno)); + return MM_ERROR_RADIO_INTERNAL; + } + } + /*Only update if the ioctl was successful*/ + radio->freq = freq; + + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_NONE; +} + +int _mmradio_get_frequency(mm_radio_t *radio, int *pFreq) +{ + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_FREQ); + + return_val_if_fail(pFreq, MM_ERROR_INVALID_ARGUMENT); + + /* update freq from handle */ + *pFreq = radio->freq; + + MMRADIO_LOG_DEBUG("Getting %d frequency\n", radio->freq); + + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_NONE; +} + +#ifdef USE_FM_RADIO_V4L2_VOLUME +static void _mmradio_fadevolume_cancel(mm_radio_t *radio) +{ + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + + MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio); + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE_RETURN_VOID(priv_sprd_v4l2); + if (priv_sprd_v4l2->volume_fade.fade_volume_thread) { + pthread_cancel(priv_sprd_v4l2->volume_fade.fade_volume_thread); + pthread_join(priv_sprd_v4l2->volume_fade.fade_volume_thread, NULL); + priv_sprd_v4l2->volume_fade.fade_volume_thread = 0; + } +} + + +static void __mmradio_fade_volume_thread(mm_radio_t *radio) +{ + int ret = 0; + int index = 0; + + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio); + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE_RETURN_VOID(priv_sprd_v4l2); + + if (priv_sprd_v4l2->volume_fade.initial_volume < priv_sprd_v4l2->volume_fade.final_volume) { + /*increasing index*/ + do { + usleep(100 * 1000); + priv_sprd_v4l2->volume_fade.initial_volume++; + ret = __mmradio_set_volume(radio, priv_sprd_v4l2->volume_fade.initial_volume); + if (ret != 0) { + /*When this happens usually state is changed*/ + priv_sprd_v4l2->volume_fade.fade_finished = MM_RADIO_TRUE; + MMRADIO_LOG_ERROR("set volume failed so no more fading for this request"); + return; + } + } while (priv_sprd_v4l2->volume_fade.initial_volume != priv_sprd_v4l2->volume_fade.final_volume); + } else { + /*decreasing index*/ + do { + usleep(100 * 1000); + priv_sprd_v4l2->volume_fade.initial_volume--; + ret = __mmradio_set_volume(radio, priv_sprd_v4l2->volume_fade.initial_volume); + if (ret != 0) { + /*When this happens usually state is changed*/ + priv_sprd_v4l2->volume_fade.fade_finished = MM_RADIO_TRUE; + MMRADIO_LOG_ERROR("set volume failed so no more fading for this request"); + return; + } + } while (priv_sprd_v4l2->volume_fade.initial_volume != priv_sprd_v4l2->volume_fade.final_volume); + } + priv_sprd_v4l2->volume_fade.fade_finished = MM_RADIO_TRUE; +} + +/* + * Description: This function fades in and out fm volume, + * pseudo: open a thread, change the volume in steps in time intervals + * */ +static void _mmradio_fadevolume(mm_radio_t *radio, int initial_volume, int final_volume) +{ + int ret = 0; + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + + MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio); + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE_RETURN_VOID(priv_sprd_v4l2); + + if (initial_volume == final_volume) { + MMRADIO_LOG_INFO("volume is same no need to fade volume"); + return; + } + + /*cancel any outstanding request*/ + _mmradio_fadevolume_cancel(radio); + + if (priv_sprd_v4l2->volume_fade.fade_finished) { + priv_sprd_v4l2->volume_fade.initial_volume = initial_volume; + } + if (!priv_sprd_v4l2->volume_fade.initial_volume) { + priv_sprd_v4l2->volume_fade.initial_volume = initial_volume; + } + + priv_sprd_v4l2->volume_fade.final_volume = final_volume; + + if (priv_sprd_v4l2->volume_fade.final_volume == priv_sprd_v4l2->volume_fade.initial_volume) { + MMRADIO_LOG_INFO("volume is same no need to fade volume"); + return; + } + + if (radio->current_state != MM_RADIO_STATE_PLAYING) { + MMRADIO_LOG_ERROR("we are not in playing state we are in state %d don't fade volume!!", radio->current_state); + return; + } + + priv_sprd_v4l2->volume_fade.fade_finished = MM_RADIO_FALSE; + MMRADIO_LOG_INFO("fade from %d to %d", priv_sprd_v4l2->volume_fade.initial_volume, priv_sprd_v4l2->volume_fade.final_volume); + + ret = pthread_create(&priv_sprd_v4l2->volume_fade.fade_volume_thread, NULL, + (void *)__mmradio_fade_volume_thread, (void *)radio); + if (ret < 0) { + MMRADIO_LOG_ERROR("fade volume thread creation failed - %d", ret); + return ; + } +} + +static int _mm_radio_recording_volume_change_policy(mm_radio_t *radio, int present_volume) +{ + /* If lower than lower threshold return lower threshold */ + if (present_volume < radio->radio_tuning.recording_volume_lower_thres) { + return radio->radio_tuning.recording_volume_lower_thres; + } + if (present_volume > radio->radio_tuning.recording_volume_heigher_thres) { + return radio->radio_tuning.recording_volume_heigher_thres; + } + return present_volume; +} + +static void __mmradio_volume_change_cb(volume_type_t type, unsigned int volume, void *user_data) +{ + mm_radio_t *radio = (mm_radio_t *)user_data; + + if (type == VOLUME_TYPE_MEDIA) { + MMRADIO_LOG_DEBUG("Change FM Radio volume to %d\n", volume); + __mmradio_set_volume(radio, volume); + } +} + +/* FIXME: for checking device is changed. This can be removed with another solution from sound-server */ +static void __mmradio_active_device_changed_cb(mm_sound_device_in device_in, mm_sound_device_out device_out, void *user_data) +{ + mm_radio_t *radio = (mm_radio_t *)user_data; + unsigned int volume = 0; + unsigned int recording_volume = 0; + + MMRADIO_LOG_DEBUG("active_device_changed: in[0x%08x], out[0x%08x]\n", device_in, device_out); + + /* normal case */ + mm_sound_volume_get_value(VOLUME_TYPE_MEDIA, &volume); + + MMRADIO_LOG_DEBUG("Change FM Radio volume to %d\n", volume); + __mmradio_set_volume(radio, volume); +} + +static int __mmradio_set_volume(mm_radio_t *radio, unsigned int value) +{ + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_VOLUME); + + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE(priv_sprd_v4l2); + + if (radio->radio_fd < 0) { + return MM_ERROR_RADIO_NOT_INITIALIZED; + } + + /*During scanning or seeing it is not advisable to control volume + * refer to PLM - P141022-00376*/ + if (radio->is_seeking || radio->current_state == MM_RADIO_STATE_SCANNING) { + MMRADIO_LOG_INFO("We are either seeking or scanning best not to set volume"); + return MM_ERROR_NONE; + } + + pthread_mutex_lock(&radio->volume_lock); + + if (radio->radio_fd > 0) { + (priv_sprd_v4l2->vctrl).id = V4L2_CID_AUDIO_VOLUME; + (priv_sprd_v4l2->vctrl).value = fm_volume_tbl[value]; + + MMRADIO_LOG_INFO("set volume:%d", (priv_sprd_v4l2->vctrl).value); + + if (ioctl(radio->radio_fd, VIDIOC_S_CTRL, &(priv_sprd_v4l2->vctrl)) < 0) { + MMRADIO_LOG_ERROR("failed to set volume %s\n", strerror(errno)); + pthread_mutex_unlock(&radio->volume_lock); + return MM_ERROR_RADIO_INTERNAL; + } + } else { + MMRADIO_LOG_WARNING("radio_fd (%d) is closed already.", radio->radio_fd); + } + + pthread_mutex_unlock(&radio->volume_lock); + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; +} + +static int __mmradio_get_volume(mm_radio_t *radio, unsigned int *value) +{ + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_VOLUME); + + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE(priv_sprd_v4l2); + + if (radio->radio_fd < 0) { + return MM_ERROR_RADIO_NOT_INITIALIZED; + } + + pthread_mutex_lock(&radio->volume_lock); + + if (radio->radio_fd > 0) { + (priv_sprd_v4l2->vctrl).id = V4L2_CID_AUDIO_VOLUME; + + if (ioctl(radio->radio_fd, VIDIOC_G_CTRL, &(priv_sprd_v4l2->vctrl)) < 0) { + *value = 0; + MMRADIO_LOG_ERROR("failed to get volume - %s\n", strerror(errno)); + pthread_mutex_unlock(&radio->volume_lock); + return MM_ERROR_RADIO_INTERNAL; + } + *value = (((priv_sprd_v4l2->vctrl).value - FM_VOLUME_BASE) / (FM_VOLUME_MAX - 1)); + } else { + MMRADIO_LOG_WARNING("radio_fd (%d) is closed already.", radio->radio_fd); + } + + pthread_mutex_unlock(&radio->volume_lock); + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; +} +#endif /* USE_FM_RADIO_V4L2_VOLUME */ + +int _mmradio_mute(mm_radio_t *radio) +{ + int ret = MM_ERROR_NONE; + + ret = mm_sound_set_route_info("fm_mute", "0"); + if (ret == MM_ERROR_NONE) { + MMRADIO_LOG_INFO("set mixer mute success"); + radio->is_muted = MM_RADIO_TRUE; + } else { + MMRADIO_LOG_ERROR("set mixer mute failed. ret =0x%x", ret); + } + return ret; +} + +int _mmradio_unmute(mm_radio_t *radio) +{ + int ret = MM_ERROR_NONE; + + ret = mm_sound_set_route_info("fm_mute", "1"); + if (ret == MM_ERROR_NONE) { + MMRADIO_LOG_INFO("set mixer unmute success"); + radio->is_muted = MM_RADIO_FALSE; + } else { + MMRADIO_LOG_ERROR("set mixer unmute failed. ret =0x%x", ret); + } + return ret; +} + +int __mmradio_mute_internal(mm_radio_t *radio) +{ + int ret = MM_ERROR_NONE; + + ret = mm_sound_set_route_info("fm_mute", "0"); + if (ret == MM_ERROR_NONE) { + MMRADIO_LOG_INFO("set mixer mute success"); + } else { + MMRADIO_LOG_ERROR("set mixer mute failed. ret =0x%x", ret); + } + return ret; +} + +int __mmradio_unmute_internal(mm_radio_t *radio) +{ + int ret = MM_ERROR_NONE; + + ret = mm_sound_set_route_info("fm_mute", "1"); + if (ret == MM_ERROR_NONE) { + MMRADIO_LOG_INFO("set mixer unmute success"); + } else { + MMRADIO_LOG_ERROR("set mixer unmute failed. ret =0x%x", ret); + } + return ret; +} + + +/* -------------------------------------------------------------------------- + * Name : __mmradio_set_band_range + * Desc : apply max and min frequency to device_mmradio_stop + * Param : + * [in] radio : radio handle + * Return : zero on success, or negative value with error code + *---------------------------------------------------------------------------*/ +static int __mmradio_set_band_range(mm_radio_t *radio) +{ + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE(priv_sprd_v4l2); + + /* get min and max freq. */ + (priv_sprd_v4l2->vt).rangelow = RADIO_FREQ_FORMAT_SET(radio->region_setting.band_min); + (priv_sprd_v4l2->vt).rangehigh = RADIO_FREQ_FORMAT_SET(radio->region_setting.band_max); + + + if (radio->radio_fd < 0) { + MMRADIO_LOG_DEBUG("Device not ready so sending 0\n"); + return MM_ERROR_RADIO_INTERNAL; + } else { + /* set it to device */ + if (ioctl(radio->radio_fd, VIDIOC_S_TUNER, &(priv_sprd_v4l2->vt)) < 0) { + MMRADIO_LOG_ERROR("failed to set band range - %s\n", strerror(errno)); + return MM_ERROR_RADIO_INTERNAL; + } + } + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; +} + +int _mmradio_set_message_callback(mm_radio_t *radio, MMMessageCallback callback, void *user_param) +{ + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + + radio->msg_cb = callback; + radio->msg_cb_param = user_param; + + MMRADIO_LOG_DEBUG("msg_cb : 0x%x msg_cb_param : 0x%x\n", (unsigned int)callback, (unsigned int)user_param); + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; +} + +int _mmradio_get_state(mm_radio_t *radio, int *pState) +{ + int state = 0; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + return_val_if_fail(pState, MM_ERROR_INVALID_ARGUMENT); + + state = __mmradio_get_state(radio); + + *pState = state; + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; +} + +int _mmradio_start(mm_radio_t *radio) +{ + int ret = MM_ERROR_NONE; + bool is_connected = false; + unsigned int volume = 0; + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_START); + + pthread_mutex_lock(&radio->state_mutex); + MMRADIO_LOG_INFO(""); + ret = _mmradio_prepare_device(radio); + if (ret) { + MMRADIO_LOG_ERROR("Coundn't prepare the device - 0x%x\n", ret); + goto error; + } + + /*Initalize tuning parameters*/ + __mm_radio_init_tuning_params(radio); + + ret = __mmradio_init_v4l2_device(radio); + if (ret) { + MMRADIO_LOG_ERROR("Coundn't init the device - 0x%x\n", ret); + goto error; + } + +#ifdef ENABLE_FM_TUNING + /*apply Tuning Parameters*/ + __mm_radio_apply_tuning_params( radio); +#endif +#ifdef USE_FM_RADIO_V4L2_VOLUME + mm_sound_volume_get_value(VOLUME_TYPE_MEDIA, &volume); + __mmradio_set_volume(radio, volume); +#endif + + /* set stored frequency */ + _mmradio_set_frequency(radio, radio->freq); + /*apply Tuning Parameters*/ + + usleep(100 * 1000); /* FIXME: reduce FM Radio turn on noise */ + +#ifdef MM_RADIO_EAR_PHONE_POLICY + ret = _mmradio_get_device_available(radio, &is_connected); + if (!is_connected) { + MMRADIO_LOG_ERROR("SOUND_DEVICE_AUDIO_JACK is not connected, radio can't play without audio jack"); + ret = MM_ERROR_RADIO_NO_ANTENNA; + goto error; + } +#endif + + +#ifdef FEATURE_ASM_SUPPORT + radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE; /*add this so asm state is always updated*/ + ret = mmradio_asm_set_state(&radio->sm, ASM_STATE_PLAYING, ASM_RESOURCE_RADIO_TUNNER); +#else + ret = mmradio_set_audio_focus(&radio->sm, _mmradio_sound_focus_watch_cb, TRUE, (void *)radio); +#endif + if (ret) { + MMRADIO_LOG_ERROR("failed to set asm state to PLAYING\n"); + goto error; + } + +#ifdef MM_RADIO_EAR_PHONE_POLICY + ret = _mmradio_get_device_available(radio, &is_connected); + if (!is_connected) { + MMRADIO_LOG_ERROR("SOUND_DEVICE_AUDIO_JACK is not connected, radio can't play without audio jack"); + ret = MM_ERROR_RADIO_NO_ANTENNA; + goto error; + } +#endif + + /* we have to set mute here when mute is set before radio_start */ + if (radio->is_muted == MM_RADIO_TRUE) { + MMRADIO_LOG_INFO("mute in start sequence"); + if (__mmradio_mute_internal(radio) != MM_ERROR_NONE) { + MMRADIO_LOG_ERROR("set mute_internal is failed\n"); + } + } + + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_PLAYING); + +#ifdef USE_GST_PIPELINE + ret = _mmradio_start_pipeline(radio); + if (ret) { + MMRADIO_LOG_ERROR("_mmradio_start_pipeline is failed\n"); + goto error; + } +#endif + MMRADIO_LOG_INFO(""); + pthread_mutex_unlock(&radio->state_mutex); + return ret; + +error: +#ifdef FEATURE_ASM_SUPPORT + if (radio->sm.state == ASM_STATE_PLAYING) { + if (mmradio_asm_set_state(&radio->sm, ASM_STATE_STOP, ASM_RESOURCE_NONE)) { + MMRADIO_LOG_ERROR("failed to set asm-state to stop"); + } + } +#endif + __mmradio_deinit_v4l2_device(radio); + + pthread_mutex_unlock(&radio->state_mutex); + _mmradio_unprepare_device(radio); + MMRADIO_LOG_ERROR(" with ret = 0x%x", ret); + return ret; +} + +int _mmradio_stop(mm_radio_t *radio) +{ + int ret = MM_ERROR_NONE; + + MMRADIO_CHECK_INSTANCE(radio); + /*MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_STOP); */ + pthread_mutex_lock(&radio->state_mutex); + + MMRADIO_CHECK_STATE_GOTO_IF_FAIL(ret, radio, MMRADIO_COMMAND_STOP, error); + MMRADIO_LOG_INFO(""); + + + radio->seek_unmute = MM_RADIO_FALSE; + /*cancel if any seek*/ + _mmradio_seek_cancel(radio); + +#ifdef USE_FM_RADIO_V4L2_VOLUME + /*If there is volume fading going on we better stop it*/ + _mmradio_fadevolume_cancel(radio); +#endif + + /* mute for stop */ + MMRADIO_LOG_INFO("mute in stop sequence"); + if (__mmradio_mute_internal(radio) != MM_ERROR_NONE) { + MMRADIO_LOG_ERROR("set mute_internal is failed\n"); + } + + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY); +#ifdef FEATURE_ASM_SUPPORT + ret = mmradio_asm_set_state(&radio->sm, ASM_STATE_STOP, ASM_RESOURCE_NONE); + if (ret) { + MMRADIO_LOG_ERROR("failed to set asm state to STOPEED\n"); + goto error; + } +#endif +#ifdef USE_GST_PIPELINE + ret = _mmradio_stop_pipeline(radio); + if (ret) { + MMRADIO_LOG_ERROR("_mmradio_stop_pipeline is failed\n"); + goto error; + } +#endif + + /*call by application*/ + if (radio->sm.by_asm_cb == MMRADIO_ASM_CB_NONE) { + __mmradio_deinit_v4l2_device(radio); + } + MMRADIO_LOG_INFO("Radio Stopped"); + + + MMRADIO_LOG_INFO(""); + pthread_mutex_unlock(&radio->state_mutex); + return ret; +error: + MMRADIO_LOG_ERROR(" with ret = 0x%x", ret); + pthread_mutex_unlock(&radio->state_mutex); + return ret; +} + +/* There is no concept of pause in radio transmission. + * This is essentially a stop call, + * but this is added to keep sound-server's state in order */ +int _mmradio_pause(mm_radio_t *radio) +{ + int ret = MM_ERROR_NONE; + + MMRADIO_CHECK_INSTANCE(radio); + + pthread_mutex_lock(&radio->state_mutex); + MMRADIO_CHECK_STATE_GOTO_IF_FAIL(ret, radio, MMRADIO_COMMAND_STOP, error); + MMRADIO_LOG_INFO(""); + + radio->seek_unmute = MM_RADIO_FALSE; + /*cancel if any seek*/ + _mmradio_seek_cancel(radio); + +#ifdef USE_FM_RADIO_V4L2_VOLUME + /*If there is volume fading going on we better stop it*/ + _mmradio_fadevolume_cancel(radio); +#endif + + /* mute for pause */ + MMRADIO_LOG_INFO("mute in pause sequence"); + if (__mmradio_mute_internal(radio) != MM_ERROR_NONE) { + MMRADIO_LOG_ERROR("set mute_internal is failed\n"); + } + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY); +#ifdef FEATURE_ASM_SUPPORT + ret = mmradio_asm_set_state(&radio->sm, ASM_STATE_PAUSE, ASM_RESOURCE_NONE); + if (ret) { + MMRADIO_LOG_ERROR("failed to set asm state to PLAYING\n"); + goto error; + } +#endif +#ifdef USE_GST_PIPELINE + ret = _mmradio_stop_pipeline(radio); + if (ret) { + MMRADIO_LOG_ERROR("_mmradio_stop_pipeline is failed\n"); + goto error; + } +#endif + + if (radio->sm.by_asm_cb == MMRADIO_ASM_CB_NONE) { + __mmradio_deinit_v4l2_device(radio); + } + MMRADIO_LOG_INFO("Radio Stopped from pause"); + MMRADIO_LOG_INFO(""); + pthread_mutex_unlock(&radio->state_mutex); + return ret; +error: + MMRADIO_LOG_ERROR(" with ret = 0x%x", ret); + pthread_mutex_unlock(&radio->state_mutex); + return ret; +} + +int _mmradio_seek(mm_radio_t *radio, MMRadioSeekDirectionType direction) +{ + int ret = 0; + + MMRADIO_LOG_INFO(""); + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SEEK); + + 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; + } + + radio->seek_unmute = MM_RADIO_FALSE; + radio->is_seeking = MM_RADIO_TRUE; + radio->seek_cancel = MM_RADIO_FALSE; + if (!radio->is_muted) { + if (_mmradio_mute(radio) != MM_ERROR_NONE) { + return MM_ERROR_RADIO_NOT_INITIALIZED; + } + radio->seek_unmute = MM_RADIO_TRUE; + } + + MMRADIO_LOG_DEBUG("trying to seek. direction[0:UP/1:DOWN) %d\n", direction); + radio->seek_direction = direction; + + ret = pthread_create(&radio->seek_thread, NULL, + (void *)__mmradio_seek_thread, (void *)radio); + + if (ret) { + MMRADIO_LOG_DEBUG("failed create thread\n"); + /*reset parameters*/ + radio->is_seeking = MM_RADIO_FALSE; + radio->seek_cancel = MM_RADIO_TRUE; + if (radio->seek_unmute) { + if (_mmradio_unmute(radio) != MM_ERROR_NONE) { + radio->seek_unmute = MM_RADIO_FALSE; + } + } + return MM_ERROR_RADIO_INTERNAL; + } + MMRADIO_LOG_INFO(""); + + return MM_ERROR_NONE; +} + +void _mmradio_seek_cancel(mm_radio_t *radio) +{ + int ret = 0; + MMRADIO_LOG_INFO(""); + + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + /*cancel any outstanding seek request*/ + radio->seek_cancel = MM_RADIO_TRUE; + if (radio->seek_thread) { + ret = pthread_mutex_trylock(&priv_sprd_v4l2->seek_cancel_mutex); + MMRADIO_LOG_DEBUG("try lock ret: %s (%d)", strerror(ret), 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(&priv_sprd_v4l2->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 = MM_RADIO_FALSE; + radio->seek_thread = 0; + } + MMRADIO_LOG_INFO(""); +} + +int _mmradio_start_scan(mm_radio_t *radio) +{ + int ret = MM_ERROR_NONE; + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_START_SCAN); + + int scan_tr_id = 0; + + pthread_mutex_lock(&radio->state_mutex); + MMRADIO_LOG_INFO(""); + + /*Initalize tuning parameters*/ + __mm_radio_init_tuning_params(radio); + + /*Lets hope that device is prepared already if not no matter we'll try to prepare*/ + MMRADIO_LOG_INFO("Starting Radio in Scan"); + ret = _mmradio_prepare_device(radio); + if (ret) { + MMRADIO_LOG_ERROR("Coundn't prepare the device - 0x%x\n", ret); + goto error; + } + ret = __mmradio_init_v4l2_device(radio); + if (ret) { + MMRADIO_LOG_ERROR("Coundn't init the device - 0x%x\n", ret); + goto error; + } +#ifdef ENABLE_FM_TUNING + /*apply Tuning Parameters*/ + __mm_radio_apply_tuning_params( radio); +#endif + + radio->stop_scan = MM_RADIO_FALSE; + + scan_tr_id = pthread_create(&radio->scan_thread, NULL, + (void *)__mmradio_scan_thread, (void *)radio); + + if (scan_tr_id != 0) { + MMRADIO_LOG_DEBUG("failed to create thread : scan\n"); + ret = MM_ERROR_RADIO_NOT_INITIALIZED; + goto error; + } + + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_SCANNING); + + MMRADIO_LOG_INFO(""); + pthread_mutex_unlock(&radio->state_mutex); + return MM_ERROR_NONE; +error: + MMRADIO_LOG_ERROR(" with ret = 0x%x", ret); + pthread_mutex_unlock(&radio->state_mutex); + return ret; +} + +int _mmradio_stop_scan(mm_radio_t *radio) +{ + MMRADIO_LOG_INFO(""); + int ret = 0; + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_STOP_SCAN); + + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE(priv_sprd_v4l2); + + radio->stop_scan = MM_RADIO_TRUE; + + if (radio->scan_thread) { + /* make sure all the search is stopped else we'll wait till search finish which is not ideal*/ + ret = pthread_mutex_trylock(&priv_sprd_v4l2->seek_cancel_mutex); + MMRADIO_LOG_DEBUG("try lock ret: %s (%d)", strerror(ret), 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(&priv_sprd_v4l2->seek_cancel_mutex); + } else { + MMRADIO_LOG_ERROR("trylock is failed but Not EBUSY. ret: %d", ret); + } + MMRADIO_LOG_DEBUG("pthread_join scan_thread"); + pthread_join(radio->scan_thread, NULL); + /*Clean up radio*/ + __mmradio_deinit_v4l2_device(radio); + radio->scan_thread = 0; + } + + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY); + +#ifdef USE_FM_RADIO_V4L2_VOLUME + /*if there were any volume changes, we better set them right here + * refer to PLM - P141022-00376*/ + { + int volume = 0; + ret = mm_sound_volume_get_value(VOLUME_TYPE_MEDIA, &volume); + if (ret) { + MMRADIO_LOG_ERROR("mm_sound_volume_get_value failed with [0x%x]", ret); + } else { + /*we are good to set volume here*/ + ret = __mmradio_set_volume(radio, volume); + if (ret) { + MMRADIO_LOG_ERROR("__mmradio_set_volume failed with [0x%x]", ret); + } + } + } +#endif + + MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_STOP, NULL); + + MMRADIO_LOG_INFO(""); + + return MM_ERROR_NONE; +} + +int _mm_radio_get_signal_strength(mm_radio_t *radio, int *value) +{ + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + return_val_if_fail(value, MM_ERROR_INVALID_ARGUMENT); + + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *) radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE(priv_sprd_v4l2); + + /* 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"); + *value = 0; + return MM_ERROR_NONE; + } else { + if (ioctl(radio->radio_fd, VIDIOC_G_TUNER, &(priv_sprd_v4l2->vt)) < 0) { + MMRADIO_LOG_ERROR("ioctl VIDIOC_G_TUNER error - %s\n", strerror(errno)); + return MM_ERROR_RADIO_INTERNAL; + } + } + + /* RSSI from controller will be in range of -128 to +127. + But V4L2 API defines the range of 0 to 65535. So convert this value + FM rssi is cannot be 1~128 dbm normally, although range is -128 to +127 */ + /* (65535 / 128) = 511.9921875. kernel will also use same value */ + *value = priv_sprd_v4l2->vt.signal / 511 /*(65535/128)*/ - 128; + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_NONE; +} + +static void __mmradio_scan_thread(mm_radio_t *radio) +{ + int ret = 0; + int prev_freq = 0; + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + 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); + + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *)radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE_RETURN_VOID(priv_sprd_v4l2); + + MMRADIO_LOG_INFO("mute in scan thread"); + if (__mmradio_mute_internal(radio) != MM_ERROR_NONE) { + MMRADIO_LOG_ERROR("set mute_internal is failed\n"); + }; + + if (_mmradio_set_frequency(radio, radio->region_setting.band_min) != MM_ERROR_NONE) { + MMRADIO_LOG_ERROR("set min freq failed during scanning. min freq: %d", radio->region_setting.band_min); + goto FINISHED; + } else { + MMRADIO_LOG_DEBUG("scan start with min freq: %d", radio->region_setting.band_min); + } + + 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; + MMMessageParamType param = {0,}; + + MMRADIO_LOG_DEBUG("try to scan"); + pthread_mutex_lock(&priv_sprd_v4l2->seek_cancel_mutex); + MMRADIO_LOG_DEBUG("search start during scanning\n"); + if (radio->stop_scan) { + MMRADIO_LOG_DEBUG("scan was canceled why search so we return"); + pthread_mutex_unlock(&priv_sprd_v4l2->seek_cancel_mutex); + goto FINISHED; + } + ret = ioctl(radio->radio_fd, VIDIOC_S_HW_FREQ_SEEK, &vs); + MMRADIO_LOG_DEBUG("search end during scanning"); + pthread_mutex_unlock(&priv_sprd_v4l2->seek_cancel_mutex); + if (ret == -1) { + if (errno == EAGAIN) { + MMRADIO_LOG_ERROR("scanning timeout\n"); + } else if (errno == EINVAL) { + MMRADIO_LOG_ERROR("The tuner index is out of bounds or the value in the type field is wrong or we were asked to stop search"); + break; + } else { + MMRADIO_LOG_ERROR("Error: %s, %d\n", strerror(errno), errno); + break; + } + } + + /* now we can get new frequency from radio device */ + + if (radio->stop_scan) + break; + + ret = ioctl(radio->radio_fd, VIDIOC_G_FREQUENCY, &(priv_sprd_v4l2->vf)); + if (ret < 0) { + MMRADIO_LOG_ERROR("VIDIOC_G_FREQUENCY failed with %s during SEEK", strerror(errno)); + } else { + freq = RADIO_FREQ_FORMAT_GET((priv_sprd_v4l2->vf).frequency); + radio->freq = freq; /* update freq in handle */ + if (freq < prev_freq) { + MMRADIO_LOG_DEBUG("scanning wrapped around. stopping scan\n"); + break; + } + + if (freq == prev_freq) { + MMRADIO_LOG_ERROR("frequency is same we wrapped around, we are finished scanning"); + break; + } + + prev_freq = param.radio_scan.frequency = freq; + MMRADIO_LOG_DEBUG("scanning : new frequency : [%d]\n", param.radio_scan.frequency); + + /* drop if max freq is scanned */ + if (param.radio_scan.frequency == radio->region_setting.band_max) { + MMRADIO_LOG_DEBUG("%d freq is dropping...and stopping scan\n", param.radio_scan.frequency); + break; + } + if (radio->stop_scan) + break; /* doesn't need to post */ + + MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_INFO, ¶m); + } + } +FINISHED: + radio->scan_thread = 0; + + if (!radio->stop_scan) { + /*Clean up radio*/ + __mmradio_deinit_v4l2_device(radio); + } + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY); + + if (!radio->stop_scan) { + +#ifdef USE_FM_RADIO_V4L2_VOLUME + /*if there were any volume changes, we better set them right here + * refer to PLM - P141022-00376*/ + { + int volume = 0; + ret = mm_sound_volume_get_value(VOLUME_TYPE_MEDIA, &volume); + if (ret) { + MMRADIO_LOG_ERROR("mm_sound_volume_get_value failed with [0x%x]", ret); + } else { + /*we are good to set volume here*/ + ret = __mmradio_set_volume(radio, volume); + if (ret) { + MMRADIO_LOG_ERROR("__mmradio_set_volume failed with [0x%x]", ret); + } + } + } +#endif + + MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_FINISH, NULL); + } + + MMRADIO_LOG_FLEAVE(); + + pthread_exit(NULL); + + return; +} + +static bool __is_tunable_frequency(mm_radio_t *radio, int freq) +{ + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + + if (freq == radio->region_setting.band_max || freq == radio->region_setting.band_min) + return MM_RADIO_FALSE; + + MMRADIO_LOG_FLEAVE(); + + return MM_RADIO_TRUE; +} + +static void __mmradio_seek_thread(mm_radio_t *radio) +{ + int ret = 0; + int freq = 0; + int volume = 0; + MMMessageParamType param = {0,}; + struct v4l2_hw_freq_seek vs = {0,}; + mm_radio_priv_v4l2_t *priv_sprd_v4l2 = NULL; + + vs.tuner = TUNER_INDEX; + vs.type = V4L2_TUNER_RADIO; + vs.wrap_around = DEFAULT_WRAP_AROUND; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio); + + priv_sprd_v4l2 = (mm_radio_priv_v4l2_t *)radio->vender_specific_handle; + MMRADIO_CHECK_INSTANCE_RETURN_VOID(priv_sprd_v4l2); + + /* 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); + + if (!radio->seek_cancel) { + MMRADIO_LOG_DEBUG("try to seek "); + pthread_mutex_lock(&priv_sprd_v4l2->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(&priv_sprd_v4l2->seek_cancel_mutex); + goto SEEK_FAILED; + } + ret = ioctl(radio->radio_fd, VIDIOC_S_HW_FREQ_SEEK, &vs); + MMRADIO_LOG_DEBUG("seek end"); + pthread_mutex_unlock(&priv_sprd_v4l2->seek_cancel_mutex); + if (ret == -1) { + if (errno == EAGAIN) { + /* FIXIT : we need retrying code here */ + MMRADIO_LOG_ERROR("seeking 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 Or we were asked to stop search."); + goto SEEK_FAILED; + } else { + MMRADIO_LOG_ERROR("Error: %s, %d\n", strerror(errno), errno); + goto SEEK_FAILED; + } + } + + /*seek -> scan causes sound fix to that issue*/ + if (radio->seek_cancel) { + goto SEEK_FAILED; + } + + /* now we can get new frequency from radio device */ + ret = ioctl(radio->radio_fd, VIDIOC_G_FREQUENCY, &(priv_sprd_v4l2->vf)); + if (ret < 0) { + MMRADIO_LOG_ERROR("VIDIOC_G_FREQUENCY failed with %s during SEEK", strerror(errno)); + goto SEEK_FAILED; + } else { + freq = RADIO_FREQ_FORMAT_GET((priv_sprd_v4l2->vf).frequency); + radio->freq = freq; /* update freq in handle */ + } + + MMRADIO_LOG_INFO("found frequency %d during seek\n", radio->freq); + + /* 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"); + goto SEEK_FAILED; + } + + if (__is_tunable_frequency(radio, freq)) {/* check if it's limit freq or not */ + /* now tune to new frequency */ + ret = _mmradio_set_frequency(radio, freq); + if (ret) { + MMRADIO_LOG_ERROR("failed to tune to new frequency\n"); + goto SEEK_FAILED; + } + } + MMRADIO_LOG_DEBUG("seek_unmute : [%d] seek_canel - [%d]\n", radio->seek_unmute, radio->seek_cancel); + 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 = _mmradio_unmute(radio); + if (ret) { + MMRADIO_LOG_ERROR("failed to un_mute failed\n"); + goto SEEK_FAILED; + } + radio->seek_unmute = MM_RADIO_FALSE; + } + + param.radio_scan.frequency = radio->prev_seek_freq = freq; + MMRADIO_LOG_DEBUG("seeking : new frequency : [%d]\n", param.radio_scan.frequency); + MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, ¶m); + } + + radio->seek_thread = 0; + radio->is_seeking = MM_RADIO_FALSE; + + /*if there were any volume changes, we better set them right here + * refer to PLM - P141022-00376*/ + mm_sound_volume_get_value(VOLUME_TYPE_MEDIA, &volume); + mm_sound_volume_set_value(VOLUME_TYPE_MEDIA, volume); + + MMRADIO_LOG_FLEAVE(); + + pthread_exit(NULL); + 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 = _mmradio_unmute(radio); + if (ret) { + MMRADIO_LOG_ERROR("failed to un_mute failed\n"); + } + radio->seek_unmute = MM_RADIO_FALSE; + } + /* freq -1 means it's failed to seek */ + param.radio_scan.frequency = -1; + MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, ¶m); + radio->is_seeking = MM_RADIO_FALSE; + + /*if there were any volume changes, we better set them right here + * refer to PLM - P141022-00376*/ + mm_sound_volume_get_value(VOLUME_TYPE_MEDIA, &volume); + mm_sound_volume_set_value(VOLUME_TYPE_MEDIA, volume); + + pthread_exit(NULL); + return; +} + +static bool __mmradio_post_message(mm_radio_t *radio, enum MMMessageType msgtype, MMMessageParamType *param) +{ + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + + if (!radio->msg_cb) { + MMRADIO_LOG_WARNING("failed to post a message\n"); + return MM_RADIO_FALSE; + } + + MMRADIO_LOG_DEBUG("address of msg_cb = %p\n", radio->msg_cb); + + radio->msg_cb(msgtype, param, radio->msg_cb_param); + + MMRADIO_LOG_FLEAVE(); + + return MM_RADIO_TRUE; +} + +static int __mmradio_check_state(mm_radio_t *radio, MMRadioCommand command) +{ + MMRadioStateType radio_state = MM_RADIO_STATE_NUM; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + + radio_state = __mmradio_get_state(radio); + + MMRADIO_LOG_DEBUG("incomming command = %d current state = %d\n", command, radio_state); + + switch (command) { + case MMRADIO_COMMAND_CREATE: { + if (radio_state != 0) + goto NO_OP; + } + break; + + case MMRADIO_COMMAND_REALIZE: { + if (radio_state == MM_RADIO_STATE_READY || + radio_state == MM_RADIO_STATE_PLAYING || + radio_state == MM_RADIO_STATE_SCANNING) + goto NO_OP; + + if (radio_state == 0) + goto INVALID_STATE; + } + break; + + case MMRADIO_COMMAND_UNREALIZE: { + if (radio_state == MM_RADIO_STATE_NULL) + goto NO_OP; + + /* we can call unrealize at any higher state */ + } + break; + + case MMRADIO_COMMAND_START: { + if (radio_state == MM_RADIO_STATE_PLAYING) + goto NO_OP; + + if (radio_state != MM_RADIO_STATE_READY) + goto INVALID_STATE; + } + break; + + case MMRADIO_COMMAND_STOP: { + if (radio_state == MM_RADIO_STATE_READY) + goto NO_OP; + + if (radio_state != MM_RADIO_STATE_PLAYING) + goto INVALID_STATE; + } + break; + + case MMRADIO_COMMAND_START_SCAN: { + if (radio_state == MM_RADIO_STATE_SCANNING) + goto NO_OP; + + if (radio_state != MM_RADIO_STATE_READY) + goto INVALID_STATE; + } + break; + + case MMRADIO_COMMAND_STOP_SCAN: { + if (radio_state == MM_RADIO_STATE_READY) + goto NO_OP; + + if (radio_state != MM_RADIO_STATE_SCANNING) + goto INVALID_STATE; + } + break; + + case MMRADIO_COMMAND_DESTROY: + case MMRADIO_COMMAND_VOLUME: + case MMRADIO_COMMAND_MUTE: + case MMRADIO_COMMAND_UNMUTE: + case MMRADIO_COMMAND_SET_FREQ: + case MMRADIO_COMMAND_GET_FREQ: + case MMRADIO_COMMAND_SET_REGION: { + /* we can do it at any state */ + } + break; + + case MMRADIO_COMMAND_SEEK: { + if (radio_state != MM_RADIO_STATE_PLAYING) + goto INVALID_STATE; + } + break; + + case MMRADIO_COMMAND_GET_REGION: { + if (radio_state == MM_RADIO_STATE_NULL) + goto INVALID_STATE; + } + break; + case MMRADIO_COMMAND_TUNE: { + if (radio_state < MM_RADIO_STATE_READY || radio_state >= MM_RADIO_STATE_NUM) + goto INVALID_STATE; + } + break; + case MMRADIO_COMMAND_RDS_START: { + if (radio_state != MM_RADIO_STATE_PLAYING) + goto INVALID_STATE; + } + break; + case MMRADIO_COMMAND_RDS_STOP: { + if (radio_state != MM_RADIO_STATE_PLAYING) + goto INVALID_STATE; + } + break; + default: + MMRADIO_LOG_DEBUG("not handled in FSM. don't care it\n"); + break; + } + + MMRADIO_LOG_DEBUG("status OK\n"); + + radio->cmd = command; + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; + + +INVALID_STATE: + MMRADIO_LOG_WARNING("invalid state. current = %d command = %d\n", + radio_state, command); + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_RADIO_INVALID_STATE; + + +NO_OP: + MMRADIO_LOG_WARNING("mm-radio is in the desired state(%d). doing noting\n", radio_state); + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_RADIO_NO_OP; + +} + +static bool __mmradio_set_state(mm_radio_t *radio, int new_state) +{ + MMMessageParamType msg = {0, }; + int msg_type = MM_MESSAGE_UNKNOWN; + + MMRADIO_LOG_FENTER(); + + if (!radio) { + MMRADIO_LOG_WARNING("calling set_state with invalid radio handle\n"); + return MM_RADIO_FALSE; + } + + if (radio->current_state == new_state && radio->pending_state == 0) { + MMRADIO_LOG_WARNING("we are in same state\n"); + return MM_RADIO_TRUE; + } + + /* set state */ + radio->old_state = radio->current_state; + radio->current_state = new_state; + + /* fill message param */ + msg.state.previous = radio->old_state; + msg.state.current = radio->current_state; + + /* post message to application */ + switch (radio->sm.by_asm_cb) { + case MMRADIO_ASM_CB_NONE: { + msg_type = MM_MESSAGE_STATE_CHANGED; + MMRADIO_POST_MSG(radio, MM_MESSAGE_STATE_CHANGED, &msg); + } + break; + + case MMRADIO_ASM_CB_POSTMSG: { + msg_type = MM_MESSAGE_STATE_INTERRUPTED; + msg.union_type = MM_MSG_UNION_CODE; + msg.code = radio->sm.event_src; + MMRADIO_POST_MSG(radio, MM_MESSAGE_STATE_INTERRUPTED, &msg); + } + break; + + case MMRADIO_ASM_CB_SKIP_POSTMSG: + default: + break; + } + + MMRADIO_LOG_FLEAVE(); + + return MM_RADIO_TRUE; +} + +static int __mmradio_get_state(mm_radio_t *radio) +{ + MMRADIO_CHECK_INSTANCE(radio); + + MMRADIO_LOG_DEBUG("radio state : current : [%d] old : [%d] pending : [%d]\n", + radio->current_state, radio->old_state, radio->pending_state); + + return radio->current_state; +} +#ifdef FEATURE_ASM_SUPPORT +static ASM_cb_result_t __mmradio_asm_callback(int handle, ASM_event_sources_t event_source, ASM_sound_commands_t command, unsigned int sound_status, void *cb_data) +{ + mm_radio_t *radio = (mm_radio_t *) cb_data; + int result = MM_ERROR_NONE; + ASM_cb_result_t cb_res = ASM_CB_RES_NONE; + + MMRADIO_LOG_FENTER(); + + radio->sm.event_src = event_source; + + switch (command) { + case ASM_COMMAND_STOP: { + MMRADIO_LOG_INFO("got ASM_COMMAND_STOP cmd. (cmd: %d event_src: %d)\n", command, event_source); + switch (event_source) { + case ASM_EVENT_SOURCE_CALL_START: + case ASM_EVENT_SOURCE_ALARM_START: + case ASM_EVENT_SOURCE_EMERGENCY_START: + case ASM_EVENT_SOURCE_EARJACK_UNPLUG: + case ASM_EVENT_SOURCE_MEDIA: + case ASM_EVENT_SOURCE_RESOURCE_CONFLICT: + case ASM_EVENT_SOURCE_NOTIFY_START: + case ASM_EVENT_SOURCE_OTHER_PLAYER_APP: + /* case ASM_EVENT_SOURCE_RESUMABLE_MEDIA: */ + { + radio->sm.by_asm_cb = MMRADIO_ASM_CB_POSTMSG; + result = _mmradio_stop(radio); + if (result) { + MMRADIO_LOG_ERROR("failed to stop radio\n"); + } + _mm_radio_event_s *event = g_slice_new0(_mm_radio_event_s); + if (event == NULL) { + cb_res = ASM_CB_RES_IGNORE; + return cb_res; + } + + event->event_type = MMRADIO_EVENT_STOP; + g_async_queue_push_sorted(radio->event_queue, event, event_comparator, NULL); + MMRADIO_LOG_DEBUG("unprepare in asm callback\n"); + radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE; + } + break; + default: { + radio->sm.by_asm_cb = MMRADIO_ASM_CB_SKIP_POSTMSG; + result = _mmradio_stop(radio); + if (result) { + MMRADIO_LOG_ERROR("failed to stop radio\n"); + } + _mm_radio_event_s *event = g_slice_new0(_mm_radio_event_s); + if (event == NULL) { + cb_res = ASM_CB_RES_IGNORE; + return cb_res; + } + + event->event_type = MMRADIO_EVENT_STOP; + g_async_queue_push_sorted(radio->event_queue, event, event_comparator, NULL); + radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE; + } + break; + } + cb_res = ASM_CB_RES_STOP; + } + break; + case ASM_COMMAND_PAUSE: { + MMRADIO_LOG_INFO("got ASM_COMMAND_PAUSE cmd. (cmd: %d event_src: %d)\n", command, event_source); + switch (event_source) { + case ASM_EVENT_SOURCE_CALL_START: + case ASM_EVENT_SOURCE_ALARM_START: + case ASM_EVENT_SOURCE_EMERGENCY_START: + case ASM_EVENT_SOURCE_EARJACK_UNPLUG: + case ASM_EVENT_SOURCE_MEDIA: + case ASM_EVENT_SOURCE_RESOURCE_CONFLICT: + case ASM_EVENT_SOURCE_NOTIFY_START: + case ASM_EVENT_SOURCE_OTHER_PLAYER_APP: + /* case ASM_EVENT_SOURCE_RESUMABLE_MEDIA: */ + { + radio->sm.by_asm_cb = MMRADIO_ASM_CB_POSTMSG; + result = _mmradio_pause(radio); + if (result) { + MMRADIO_LOG_ERROR("failed to pause radio\n"); + } + _mm_radio_event_s *event = g_slice_new0(_mm_radio_event_s); + if (event == NULL) { + cb_res = ASM_CB_RES_IGNORE; + return cb_res; + } + + event->event_type = MMRADIO_EVENT_STOP; + g_async_queue_push_sorted(radio->event_queue, event, event_comparator, NULL); + radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE; + } + break; +#if 0 + /* to handle timer recording with RADIO_INTERRUPTED_BY_RESUME_CANCEL */ + case ASM_EVENT_SOURCE_RESUMABLE_CANCELED: { + MMRadioStateType radio_cur_state = MM_RADIO_STATE_NUM; + radio_cur_state = __mmradio_get_state(radio); + radio->sm.by_asm_cb = MMRADIO_ASM_CB_POSTMSG; + if (radio_cur_state == MM_RADIO_STATE_READY) { + MMMessageParamType msg = {0, }; + int msg_type = MM_MESSAGE_UNKNOWN; + + msg_type = MM_MESSAGE_STATE_INTERRUPTED; + msg.union_type = MM_MSG_UNION_CODE; + msg.code = radio->sm.event_src; + MMRADIO_LOG_INFO("send RADIO_INTERRUPTED_BY_RESUME_CANCEL to clear timer. (cmd: %d event_src: %d)\n", command, event_source); + MMRADIO_POST_MSG(radio, MM_MESSAGE_STATE_INTERRUPTED, &msg); + } + radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE; + } + break; +#endif + default: { + MMRADIO_LOG_WARNING("ASM_COMMAND_PAUSE but event_source is %d\n", event_source); + radio->sm.by_asm_cb = MMRADIO_ASM_CB_SKIP_POSTMSG; + result = _mmradio_pause(radio); + if (result) { + MMRADIO_LOG_ERROR("failed to pause radio\n"); + } + _mm_radio_event_s *event = g_slice_new0(_mm_radio_event_s); + if (event == NULL) { + cb_res = ASM_CB_RES_IGNORE; + return cb_res; + } + + event->event_type = MMRADIO_EVENT_STOP; + g_async_queue_push_sorted(radio->event_queue, event, event_comparator, NULL); + radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE; + } + break; + } + cb_res = ASM_CB_RES_PAUSE; + } + break; + + case ASM_COMMAND_PLAY: + case ASM_COMMAND_RESUME: { + MMMessageParamType msg = {0,}; + msg.union_type = MM_MSG_UNION_CODE; + msg.code = event_source; + + if (command == ASM_COMMAND_PLAY) + MMRADIO_LOG_INFO("got ASM_COMMAND_PLAY (cmd: %d event_src: %d)\n", command, event_source); + else if (command == ASM_COMMAND_RESUME) + MMRADIO_LOG_INFO("got ASM_COMMAND_RESUME (cmd: %d event_src: %d)\n", command, event_source); + + MMRADIO_LOG_DEBUG("Got ASM resume message by %d\n", msg.code); + MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg); + + cb_res = ASM_CB_RES_IGNORE; + radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE; + } + break; + + default: + break; + } + + MMRADIO_LOG_FLEAVE(); + + return cb_res; +} +#else +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, + const char *additional_info, void *user_data) +{ + mm_radio_t *radio = (mm_radio_t *) user_data; + ASM_event_sources_t event_source; + int result = MM_ERROR_NONE; + int postMsg = false; + + MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_INSTANCE(radio); + + mmradio_get_audio_focus_reason(focus_state, reason_for_change, &event_source, &postMsg); + radio->sm.event_src = event_source; + + switch (focus_state) { + case FOCUS_IS_RELEASED: + radio->sm.by_asm_cb = MMRADIO_ASM_CB_POSTMSG; + result = _mmradio_stop(radio); + if (result) { + MMRADIO_LOG_ERROR("failed to stop radio\n"); + } + MMRADIO_LOG_DEBUG("FOCUS_IS_RELEASED\n"); + break; + + case FOCUS_IS_ACQUIRED: { + MMMessageParamType msg = {0,}; + msg.union_type = MM_MSG_UNION_CODE; + msg.code = event_source; + if (postMsg) + MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg); + + radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE; + + MMRADIO_LOG_DEBUG("FOCUS_IS_ACQUIRED\n"); + } + break; + + default: + MMRADIO_LOG_DEBUG("Unknown focus_state\n"); + break; + } + MMRADIO_LOG_FLEAVE(); +} + +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; + ASM_event_sources_t event_source; + int result = MM_ERROR_NONE; + int postMsg = false; + + MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_INSTANCE(radio); + + mmradio_get_audio_focus_reason(!focus_state, reason_for_change, &event_source, &postMsg); + radio->sm.event_src = event_source; + + switch (focus_state) { + case FOCUS_IS_RELEASED: { + MMMessageParamType msg = {0,}; + msg.union_type = MM_MSG_UNION_CODE; + msg.code = event_source; + if (postMsg) + MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg); + + radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE; + + MMRADIO_LOG_DEBUG("FOCUS_IS_ACQUIRED postMsg: %d\n", postMsg); + } + break; + + case FOCUS_IS_ACQUIRED: { + radio->sm.by_asm_cb = MMRADIO_ASM_CB_POSTMSG; + result = _mmradio_stop(radio); + if (result) { + MMRADIO_LOG_ERROR("failed to stop radio\n"); + } + MMRADIO_LOG_DEBUG("FOCUS_IS_RELEASED\n"); + break; + } + break; + + default: + MMRADIO_LOG_DEBUG("Unknown focus_state postMsg : %d\n", postMsg); + break; + } + MMRADIO_LOG_FLEAVE(); +} +#endif +int _mmradio_get_region_type(mm_radio_t *radio, MMRadioRegionType *type) +{ + MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION); + + return_val_if_fail(type, MM_ERROR_INVALID_ARGUMENT); + + *type = radio->region_setting.country; + + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_NONE; +} + +int _mmradio_get_region_frequency_range(mm_radio_t *radio, unsigned int *min_freq, unsigned int *max_freq) +{ + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION); + + return_val_if_fail(min_freq && max_freq, MM_ERROR_INVALID_ARGUMENT); + + *min_freq = radio->region_setting.band_min; + *max_freq = radio->region_setting.band_max; + + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_NONE; +} + +int _mmradio_get_channel_spacing(mm_radio_t *radio, unsigned int *ch_spacing) +{ + MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_INSTANCE(radio); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION); + + return_val_if_fail(ch_spacing, MM_ERROR_INVALID_ARGUMENT); + + *ch_spacing = radio->region_setting.channel_spacing; + + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_NONE; +} + +#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("avsysaudio"); + + radio->pGstreamer_s->avsysaudiosrc = gst_element_factory_make("avsysaudiosrc", "fm audio src"); + radio->pGstreamer_s->queue2 = gst_element_factory_make("queue2", "queue2"); + radio->pGstreamer_s->avsysaudiosink = gst_element_factory_make("avsysaudiosink", "audio sink"); + + g_object_set(radio->pGstreamer_s->avsysaudiosrc, "latency", 2, NULL); + g_object_set(radio->pGstreamer_s->avsysaudiosink, "sync", false, NULL); + + if (!radio->pGstreamer_s->pipeline || !radio->pGstreamer_s->avsysaudiosrc || !radio->pGstreamer_s->queue2 || !radio->pGstreamer_s->avsysaudiosink) { + mmf_debug(MMF_DEBUG_ERROR, "[%s][%05d] One element could not be created. Exiting.\n", __func__, __LINE__); + return MM_ERROR_RADIO_NOT_INITIALIZED; + } + + gst_bin_add_many(GST_BIN(radio->pGstreamer_s->pipeline), + radio->pGstreamer_s->avsysaudiosrc, + radio->pGstreamer_s->queue2, + radio->pGstreamer_s->avsysaudiosink, + NULL); + if (!gst_element_link_many( + radio->pGstreamer_s->avsysaudiosrc, + radio->pGstreamer_s->queue2, + radio->pGstreamer_s->avsysaudiosink, + NULL)) { + mmf_debug(MMF_DEBUG_ERROR, "[%s][%05d] Fail to link b/w appsrc and ffmpeg in rotate\n", __func__, __LINE__); + return MM_ERROR_RADIO_NOT_INITIALIZED; + } + 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) { + mmf_debug(MMF_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; + } + + ret_state = gst_element_get_state(radio->pGstreamer_s->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); + if (ret_state == GST_STATE_CHANGE_FAILURE) { + mmf_debug(MMF_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 { + mmf_debug(MMF_DEBUG_LOG, "[%s][%05d] GST_STATE_NULL ret_state = %d (GST_STATE_CHANGE_SUCCESS)\n", __func__, __LINE__, ret_state); + } + 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) { + mmf_debug(MMF_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; + } + + ret_state = gst_element_get_state(radio->pGstreamer_s->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); + if (ret_state == GST_STATE_CHANGE_FAILURE) { + mmf_debug(MMF_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 { + mmf_debug(MMF_DEBUG_LOG, "[%s][%05d] GST_STATE_NULL ret_state = %d (GST_STATE_CHANGE_SUCCESS)\n", __func__, __LINE__, ret_state); + } + return ret; +} + +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) { + mmf_debug(MMF_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; + } + + ret_state = gst_element_get_state(radio->pGstreamer_s->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); + if (ret_state == GST_STATE_CHANGE_FAILURE) { + mmf_debug(MMF_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 { + mmf_debug(MMF_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; +} +#endif + + +static int append_variant(DBusMessageIter *iter, const char *sig, char *param[]) +{ + char *ch; + int i; + int int_type; + unsigned long long int64_type; + + if (!sig || !param) + return 0; + + for (ch = (char *)sig, i = 0; *ch != '\0'; ++i, ++ch) { + switch (*ch) { + case 'i': + int_type = atoi(param[i]); + dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &int_type); + break; + case 'u': + int_type = atoi(param[i]); + dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &int_type); + break; + case 't': + int64_type = atoi(param[i]); + dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT64, &int64_type); + break; + case 's': + dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, ¶m[i]); + break; + default: + return -EINVAL; + } + } + + return 0; +} + +#define DESTINATION "org.tizen.system.deviced" +#define PATH "/Org/Tizen/System/DeviceD/Bluetooth" +#define INTERFACE "org.tizen.system.deviced.bluetooth" +#define METHOD_TURN_ON "TurnOn" +#define METHOD_TURN_OFF "TurnOff" +#define METHOD_GET_STATE "GetState" +#define BLUETOOTH_STATE_ACTIVE "active" +#define BLUETOOTH_STATE_INACTIVE "inactive" + +static int __mmradio_enable_bluetooth(mm_radio_t *radio, int enable) +{ + DBusConnection *conn; + DBusMessage *msg; + DBusMessageIter iter; + DBusMessage *reply; + DBusError err; + + int r; + const char *dest = DESTINATION; + const char *path = PATH; + const char *interface = INTERFACE; + const char *method = enable > 0 ? METHOD_TURN_ON : METHOD_TURN_OFF; + char *param[1]; + + conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); + if (!conn) { + MMRADIO_LOG_ERROR("dbus_bus_get error"); + return MM_ERROR_RADIO_INTERNAL; + } + + MMRADIO_LOG_INFO("try to send (%s, %s, %s, %s)", dest, path, interface, method); + + msg = dbus_message_new_method_call(dest, path, interface, method); + if (!msg) { + MMRADIO_LOG_ERROR("dbus_message_new_method_call(%s:%s-%s)", path, interface, method); + return MM_ERROR_RADIO_INTERNAL; + } + param[0] = "fmradio"; + + dbus_message_iter_init_append(msg, &iter); + r = append_variant(&iter, "s", param); + if (r < 0) { + MMRADIO_LOG_ERROR("append_variant error(%d)", r); + dbus_message_unref(msg); + return MM_ERROR_RADIO_INTERNAL; + } + + dbus_error_init(&err); + + reply = dbus_connection_send_with_reply_and_block(conn, msg, DBUS_TIMEOUT_USE_DEFAULT, &err); + if (!reply) { + MMRADIO_LOG_ERROR("dbus_connection_send error(No reply)"); + } + + if (dbus_error_is_set(&err)) { + MMRADIO_LOG_ERROR("dbus_connection_send error(%s:%s)", err.name, err.message); + dbus_message_unref(msg); + dbus_error_free(&err); + return MM_ERROR_RADIO_INTERNAL; + } + + dbus_message_unref(msg); + dbus_error_free(&err); + + return MM_ERROR_NONE; +} + +static int __mmradio_wait_bluetooth_ready(mm_radio_t *radio, int wait_active, int retry_count) +{ + DBusConnection *conn; + DBusMessage *msg = NULL; + DBusMessage *reply = NULL; + DBusError err; + + int ret = MM_ERROR_RADIO_INTERNAL; + const char *dest = DESTINATION; + const char *path = PATH; + const char *interface = INTERFACE; + const char *method = METHOD_GET_STATE; + const int wait = 100 * 1000; /* 100 msec */ + + conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); + if (!conn) { + MMRADIO_LOG_ERROR("dbus_bus_get error"); + goto error; + } + + MMRADIO_LOG_INFO("try to send (%s, %s, %s, %s)", dest, path, interface, method); + + msg = dbus_message_new_method_call(dest, path, interface, method); + if (!msg) { + MMRADIO_LOG_ERROR("dbus_message_new_method_call(%s:%s-%s)", path, interface, method); + goto error; + } + + while (retry_count--) { + dbus_error_init(&err); + reply = dbus_connection_send_with_reply_and_block(conn, msg, DBUS_TIMEOUT_USE_DEFAULT, &err); + if (!reply) { + MMRADIO_LOG_ERROR("dbus_connection_send error(No reply)"); + goto error; + } else { + const char *state; + /* if bluetooth is turn on by bt framework, it would be returned "active" */ + if (MM_RADIO_FALSE == dbus_message_get_args(reply, &err, DBUS_TYPE_STRING, &state, DBUS_TYPE_INVALID)) { + MMRADIO_LOG_ERROR("dbus_message_get_args error(%s:%s)", err.name, err.message); + goto error; + } + + if (wait_active == MM_RADIO_TRUE) { + MMRADIO_LOG_INFO("wait for active state. current state (%s)", state); + if (strncmp(BLUETOOTH_STATE_ACTIVE, state, strlen(BLUETOOTH_STATE_ACTIVE))) { + usleep(wait); + continue; + } else { + ret = MM_ERROR_NONE; + break; + } + } else { + MMRADIO_LOG_INFO("wait for inactive state. current state (%s)", state); + if (strncmp(BLUETOOTH_STATE_INACTIVE, state, strlen(BLUETOOTH_STATE_INACTIVE))) { + usleep(wait); + ret = MM_ERROR_RADIO_INVALID_STATE; + break; + } else { + ret = MM_ERROR_NONE; + break; + } + } + } + } + + +error: + if (dbus_error_is_set(&err)) { + MMRADIO_LOG_ERROR("dbus_connection_send error(%s:%s)", err.name, err.message); + reply = NULL; + } + + if (msg != NULL) + dbus_message_unref(msg); + dbus_error_free(&err); + + return ret; + +} + + +void __mm_radio_init_tuning_params(mm_radio_t *radio) +{ + MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_INSTANCE_RETURN_VOID( radio ); + int not_found = -1; + int value = 0; + dictionary * dict = NULL; + +#ifdef TUNING_ENABLE /* for eng binary only */ + dict = iniparser_load(MMFW_RADIO_TUNING_TEMP_FILE); + if (!dict) { + MMRADIO_LOG_WARNING("%s load failed. use default file", MMFW_RADIO_TUNING_TEMP_FILE); + dict = iniparser_load(MMFW_RADIO_TUNING_DEFUALT_FILE); + if (!dict) { + MMRADIO_LOG_ERROR("%s load failed", MMFW_RADIO_TUNING_DEFUALT_FILE); + return; + } else { + MMRADIO_LOG_WARNING("%s is loaded.", MMFW_RADIO_TUNING_DEFUALT_FILE); + } + } else { + MMRADIO_LOG_WARNING("we read temp tuning file. (%s) this means we are on TUNING!", MMFW_RADIO_TUNING_TEMP_FILE); + } +#else + dict = iniparser_load(MMFW_RADIO_TUNING_DEFUALT_FILE); + if (!dict) { + MMRADIO_LOG_ERROR("%s load failed", MMFW_RADIO_TUNING_DEFUALT_FILE); + return; + } else { + MMRADIO_LOG_INFO("we read default tuning file. (%s)", MMFW_RADIO_TUNING_DEFUALT_FILE); + } +#endif + +#ifdef ENABLE_SPRD /* read sc2331 tuning param */ + + value = iniparser_getint(dict, MMFW_RADIO_TUNING_RSSI_THR, not_found); + if (value == not_found) { + MMRADIO_LOG_ERROR("Can't get RSSI Threshold Value"); + } + else { + radio->radio_tuning.rssi_th = value; + } + value = 0; + + value = iniparser_getint(dict, MMFW_RADIO_TUNING_FREQUENCY_OFFSET, not_found); + if (value == not_found) { + MMRADIO_LOG_ERROR("Can't get FREQUENCY_OFFSET Value"); + } + else { + radio->radio_tuning.freq_offset = value; + } + value = 0; + + value = iniparser_getint(dict, MMFW_RADIO_TUNING_NOISE_POWER, not_found); + if (value == not_found) { + MMRADIO_LOG_ERROR("Can't get NOISE_POWER Value"); + } + else { + radio->radio_tuning.noise_power = value; + } + value = 0; + + value = iniparser_getint(dict, MMFW_RADIO_TUNING_PILOT_POWER, not_found); + if (value == not_found) { + MMRADIO_LOG_ERROR("Can't get PILOT_POWER Value"); + } + else { + radio->radio_tuning.pilot_power = value; + } + value = 0; + + + /* this is not for tuning, for disable/enable softmute for sc2331 */ + value = iniparser_getint(dict, MMFW_RADIO_TUNING_SOFTMUTE_ENABLE, not_found); + if (value == not_found) { + MMRADIO_LOG_ERROR("Can't get SOFTMUTE_ENABLE Value. enable softmute by default."); + radio->radio_tuning.softmute_enable = 1; /* if we can not find ini, we will just enable softmute by default */ + } + else { + radio->radio_tuning.softmute_enable = value; + MMRADIO_LOG_INFO("SOFTMUTE_ENABLE : %d", radio->radio_tuning.softmute_enable); + } + value = 0; + +#endif + + /*Cleanup*/ + iniparser_freedict(dict); + MMRADIO_LOG_FLEAVE(); +} + +void __mm_radio_apply_tuning_params(mm_radio_t *radio) +{ + MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_INSTANCE_RETURN_VOID( radio ); + int ret = 0; + /*we only set if the values have been read correctly*/ + +#ifdef ENABLE_SPRD + /* RSSI Threshold*/ + if (radio->radio_tuning.rssi_th) { + ret = _mm_set_tuning_value(FMRX_RSSI_LEVEL_THRESHOLD, radio->radio_tuning.rssi_th); + if (ret) { + MMRADIO_LOG_ERROR("_mm_set_tuning_value failed with error = %d", ret); + } + } + + if (radio->radio_tuning.freq_offset) { + ret = _mm_set_tuning_value(FMRX_TUNING_FREQ_OFFSET, radio->radio_tuning.freq_offset); + if (ret) { + MMRADIO_LOG_ERROR("_mm_set_tuning_value failed with error = %d", ret); + } + } + + if (radio->radio_tuning.noise_power) { + ret = _mm_set_tuning_value(FMRX_TUNING_NOISE_POWER, radio->radio_tuning.noise_power); + if (ret) { + MMRADIO_LOG_ERROR("_mm_set_tuning_value failed with error = %d", ret); + } + } + + if (radio->radio_tuning.pilot_power) { + ret = _mm_set_tuning_value(FMRX_TUNING_PILOT_POWER, radio->radio_tuning.pilot_power); + if (ret) { + MMRADIO_LOG_ERROR("_mm_set_tuning_value failed with error = %d", ret); + } + } + + MMRADIO_LOG_INFO("softmute is %s. set sysfs", radio->radio_tuning.softmute_enable ? "Enabled" : "Disabled"); + ret = _mm_set_tuning_value(FMRX_TUNING_ENABLE_DISABLE_SOFTMUTE, radio->radio_tuning.softmute_enable); + if (ret) { + MMRADIO_LOG_ERROR("_mm_set_tuning_value(softmute enable) failed with error = %d", ret); + } +#endif + + MMRADIO_LOG_FLEAVE(); +} + +int _mm_set_tuning_value(char* file_name, int value) +{ +#ifdef ENABLE_FM_TUNING + FILE *tuning_file = NULL; + tuning_file = fopen(file_name, "w"); + if (!tuning_file) { + MMRADIO_LOG_ERROR("could not open file %s with error: %s (%d)", file_name, strerror(errno), errno); + return errno; + } + fprintf(tuning_file, "%d", value); + MMRADIO_LOG_INFO("value %s set to= %d", file_name, value); + + fclose(tuning_file); + tuning_file = NULL; +#endif + return 0; +} + +int _mm_radio_load_volume_table(int **volume_table, int *number_of_elements) +{ + dictionary *dict = NULL; + const char delimiter[] = ", "; + char *ptr = NULL; + char *token = NULL; + char *list_str = NULL; + int *temp_table = NULL; + int index = 0; + int ret = 0; + + bool tuning_enable = MM_RADIO_FALSE; + int not_found = -1; + int value = 0; + + dict = iniparser_load(MMFW_RADIO_TUNING_DEFUALT_FILE); + if (dict == NULL) { + MMRADIO_LOG_ERROR("%s load failed", MMFW_RADIO_TUNING_DEFUALT_FILE); + return MM_ERROR_RADIO_INTERNAL; + } else { + /*tuning enable */ + value = iniparser_getboolean(dict, MMFW_RADIO_TUNING_ENABLE, not_found); + if (value == not_found) { + MMRADIO_LOG_ERROR("Can't get Tuning Enable value"); + } else { + tuning_enable = value; + MMRADIO_LOG_INFO("Tuning enabled."); + } + + iniparser_freedict(dict); /*Cleanup*/ + } + + + if (tuning_enable == MM_RADIO_TRUE) { + dict = iniparser_load(MMFW_RADIO_TUNING_TEMP_FILE); + if (!dict) { + MMRADIO_LOG_WARNING("%s load failed. Use temporary file", MMFW_RADIO_TUNING_TEMP_FILE); + dict = iniparser_load(MMFW_RADIO_TUNING_DEFUALT_FILE); + if (!dict) { + MMRADIO_LOG_ERROR("%s load failed", MMFW_RADIO_TUNING_DEFUALT_FILE); + return MM_ERROR_RADIO_INTERNAL; + } + } + } else { + dict = iniparser_load(MMFW_RADIO_TUNING_DEFUALT_FILE); + if (!dict) { + MMRADIO_LOG_ERROR("%s load failed", MMFW_RADIO_TUNING_DEFUALT_FILE); + return MM_ERROR_RADIO_INTERNAL; + } + } + + *number_of_elements = iniparser_getint(dict, MMFW_RADIO_TUNING_VOLUME_LEVELS, -1); + if (*number_of_elements == -1) { + ret = MM_ERROR_INVALID_ARGUMENT; + goto error; + } + temp_table = (int *)malloc((*number_of_elements) * sizeof(int)); + if (!temp_table) { + goto error; + } + *volume_table = temp_table; + + list_str = iniparser_getstr(dict, MMFW_RADIO_TUNING_VOLUME_TABLE); + if (list_str) { + token = strtok_r(list_str, delimiter, &ptr); + while (token) { + temp_table[index] = atoi(token); + MMRADIO_LOG_INFO("fm volume index %d is %d", index, temp_table[index]); + index++; + token = strtok_r(NULL, delimiter, &ptr); + } + } +error: + iniparser_freedict(dict); + return ret; +} + +int _mmradio_get_device_available(mm_radio_t *radio , bool *is_connected) +{ + mm_sound_device_flags_e flags = MM_SOUND_DEVICE_STATE_ACTIVATED_FLAG; + MMSoundDeviceList_t device_list; + MMSoundDevice_t device_h = NULL; + mm_sound_device_type_e device_type; + mm_sound_device_type_e current_device = MM_SOUND_DEVICE_TYPE_BUILTIN_SPEAKER; + int ret = MM_ERROR_NONE; + + MMRADIO_LOG_FENTER(); + + /* get status if speaker is activated */ + /* (1) get current device list */ + ret = mm_sound_get_current_device_list(flags, &device_list); + if (ret) { + MMRADIO_LOG_FLEAVE(); + MMRADIO_LOG_DEBUG("mm_sound_get_current_device_list() failed [%x]!!", ret); + return MM_ERROR_RADIO_NO_ANTENNA; + } + + while (current_device <= MM_SOUND_DEVICE_TYPE_USB_AUDIO) { + /* (2) get device handle of device list */ + ret = mm_sound_get_next_device(device_list, &device_h); + + if (ret) { + MMRADIO_LOG_DEBUG("mm_sound_get_next_device() failed [%x]!!", ret); + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_RADIO_NO_ANTENNA; + } + + /* (3) get device type */ + ret = mm_sound_get_device_type(device_h, &device_type); + + if (ret) { + MMRADIO_LOG_DEBUG("mm_sound_get_device_type() failed [%x]!!", ret); + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_RADIO_NO_ANTENNA; + } + + MMRADIO_LOG_DEBUG("device_type [%d]!!", device_type); + if (device_type == MM_SOUND_DEVICE_TYPE_AUDIOJACK) { + *is_connected = TRUE; + return MM_ERROR_NONE; + } + + current_device++; + } + + MMRADIO_LOG_DEBUG("ret [%d] is_connected : %d!!", ret, *is_connected); + MMRADIO_LOG_FLEAVE(); + + return ret; + +} + diff --git a/src/mm_radio_utils.c b/src/mm_radio_utils.c new file mode 100644 index 0000000..b8bc3b4 --- /dev/null +++ b/src/mm_radio_utils.c @@ -0,0 +1,37 @@ +/* + * libmm-radio + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: JongHyuk Choi , YoungHwan An + * + * 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 FILES | +| | +========================================================================================== */ +#include +#include "mm_radio_priv_common.h" + +int event_comparator(gconstpointer a, gconstpointer b, gpointer user_data) +{ + _mm_radio_event_s *event_a = a; + _mm_radio_event_s *event_b = b; + + /* we can add some checking logic here */ + return event_a->event_type - event_b->event_type; +} diff --git a/test/mm_radio_rt_api_test.c b/test/mm_radio_rt_api_test.c index 6a881ff..eadb0b1 100644 --- a/test/mm_radio_rt_api_test.c +++ b/test/mm_radio_rt_api_test.c @@ -23,143 +23,134 @@ #include "mm_radio.h" #include "mm_radio_rt_api_test.h" -#define MENU_ITEM_MAX 19 +#define MENU_ITEM_MAX 20 #define _MAX_INPUT_STRING_ 100 static int __menu(void); -static void __call_api( int choosen ); +static void __call_api(int choosen); static int __msg_rt_callback(int message, void *param, void *user_param); static MMHandleType g_my_radio = 0; -void __call_api( int choosen ) +void __call_api(int choosen) { int ret = MM_ERROR_NONE; - switch( choosen ) - { - case 1: - { - RADIO_TEST__( mm_radio_create( &g_my_radio ); ) - RADIO_TEST__( mm_radio_set_message_callback( g_my_radio, __msg_rt_callback, g_my_radio); ) - } - break; + switch (choosen) { + case 1: { + RADIO_TEST__(mm_radio_create(&g_my_radio);) + RADIO_TEST__(mm_radio_set_message_callback(g_my_radio, __msg_rt_callback, g_my_radio);) + } + break; - case 2: - { - RADIO_TEST__( mm_radio_destroy( g_my_radio ); ) - g_my_radio = 0; - } - break; + case 2: { + RADIO_TEST__(mm_radio_destroy(g_my_radio);) + g_my_radio = 0; + } + break; - case 3: - { - RADIO_TEST__( mm_radio_realize(g_my_radio ); ) - } - break; + case 3: { + RADIO_TEST__(mm_radio_realize(g_my_radio);) + } + break; - case 4: - { - RADIO_TEST__( mm_radio_unrealize(g_my_radio ); ) - } - break; + case 4: { + RADIO_TEST__(mm_radio_unrealize(g_my_radio);) + } + break; - case 7: - { - MMRadioStateType state = 0; - RADIO_TEST__( mm_radio_get_state(g_my_radio, &state); ) + case 7: { + MMRadioStateType state = 0; + RADIO_TEST__(mm_radio_get_state(g_my_radio, &state);) - printf("state : %d\n", state); - } - break; + printf("state : %d\n", state); + } + break; - case 8: - { - RADIO_TEST__( mm_radio_start(g_my_radio); ) - } - break; + case 8: { + RADIO_TEST__(mm_radio_start(g_my_radio);) + } + break; - case 9: - { - RADIO_TEST__( mm_radio_stop(g_my_radio); ) - } - break; + case 9: { + RADIO_TEST__(mm_radio_stop(g_my_radio);) + } + break; - case 10: - { - int direction = 0; - printf("input seek direction(0:UP/1:DOWN) : "); - if (scanf("%d", &direction) == 0) - return; + case 10: { + int direction = 0; + printf("input seek direction(0:UP/1:DOWN) : "); + if (scanf("%d", &direction) == 0) + return; - RADIO_TEST__( mm_radio_seek(g_my_radio, direction); ) - } - break; + RADIO_TEST__(mm_radio_seek(g_my_radio, direction);) + } + break; - case 11: - { - int freq = 0; - printf("input freq : "); - if (scanf("%d", &freq) == 0) - return; + case 11: { + int freq = 0; + printf("input freq : "); + if (scanf("%d", &freq) == 0) + return; - RADIO_TEST__( mm_radio_set_frequency(g_my_radio, freq); ) - } - break; + RADIO_TEST__(mm_radio_set_frequency(g_my_radio, freq);) + } + break; - case 12: - { - int freq = 0; - RADIO_TEST__( mm_radio_get_frequency(g_my_radio, &freq ); ) + case 12: { + int freq = 0; + RADIO_TEST__(mm_radio_get_frequency(g_my_radio, &freq);) - printf("freq : %d\n", freq); - } - break; + printf("freq : %d\n", freq); + } + break; - case 13: - { - RADIO_TEST__( mm_radio_scan_start(g_my_radio); ) - } - break; + case 13: { + RADIO_TEST__(mm_radio_scan_start(g_my_radio);) + } + break; - case 14: - { - RADIO_TEST__( mm_radio_scan_stop(g_my_radio); ) - } - break; - - case 16: - { - int muted = 0; - printf("select one(0:UNMUTE/1:MUTE) : "); - if ( scanf("%d", &muted) == 0) - return; - RADIO_TEST__( mm_radio_set_mute(g_my_radio, muted); ) - } - break; + case 14: { + RADIO_TEST__(mm_radio_scan_stop(g_my_radio);) + } + break; + + case 16: { + int muted = 0; + printf("select one(0:UNMUTE/1:MUTE) : "); + if (scanf("%d", &muted) == 0) + return; + RADIO_TEST__(mm_radio_set_mute(g_my_radio, muted);) + } + break; + + case 17: { + MMRadioRegionType type = 0; + RADIO_TEST__(mm_radio_get_region_type(g_my_radio, &type);) + printf("region type : %d\n", type); + } + break; + + case 18: { + unsigned int min_freq = 0; + unsigned int max_freq = 0; + RADIO_TEST__(mm_radio_get_region_frequency_range(g_my_radio, &min_freq, &max_freq);) + printf("region band range: %d ~ %d KHz\n", min_freq, max_freq); + } + break; + case 19: { + int signal_strength = 0; + RADIO_TEST__(mm_radio_get_signal_strength(g_my_radio, &signal_strength);) + printf("signal strength is : %d \n", signal_strength); + } + break; + case 20: { + int channel_spacing = 0; + RADIO_TEST__(mm_radio_get_channel_spacing(g_my_radio, &channel_spacing);) + printf("channel_spacing is : %d \n", channel_spacing); + } + break; - case 17: - { - MMRadioRegionType type = 0; - RADIO_TEST__( mm_radio_get_region_type(g_my_radio, &type ); ) - printf("region type : %d\n", type); - } - break; - - case 18: - { - unsigned int min_freq = 0; - unsigned int max_freq = 0; - RADIO_TEST__( mm_radio_get_region_frequency_range(g_my_radio, &min_freq, &max_freq ); ) - printf("region band range: %d ~ %d KHz\n", min_freq, max_freq); - } - break; - case 19: - { - int signal_strength = 0; - RADIO_TEST__( mm_radio_get_signal_strength(g_my_radio, &signal_strength); ) - printf("signal strength is : %d \n", signal_strength); - } default: break; } @@ -167,19 +158,18 @@ void __call_api( int choosen ) int mm_radio_rt_api_test(void) { - while(1) - { + while (1) { int choosen = 0; choosen = __menu(); - if ( choosen == -1) + if (choosen == -1) continue; - if ( choosen == 0 ) + if (choosen == 0) break; - __call_api( choosen ); + __call_api(choosen); } printf("radio test client finished\n"); @@ -210,22 +200,21 @@ int __menu(void) printf("[17] mm_radio_get_region_type\n"); printf("[18] mm_radio_get_region_frequency_range\n"); printf("[19] mm_radio_signal_strength\n"); + printf("[20] mm_radio_get_channel_spacing\n"); printf("[0] quit\n"); printf("---------------------------------------------------------\n"); printf("choose one : "); - - if ( scanf("%d", &menu_item) == 0) - { + + if (scanf("%d", &menu_item) == 0) { char temp[_MAX_INPUT_STRING_]; - if (scanf("%s", temp) ==0) - { - printf("Error while flushing the input buffer - but lets continue\n"); - } + if (scanf("%s", temp) == 0) { + printf("Error while flushing the input buffer - but lets continue\n"); + } return -1; - } + } - if ( menu_item > MENU_ITEM_MAX ) + if (menu_item > MENU_ITEM_MAX) menu_item = -1; return menu_item; @@ -234,49 +223,48 @@ int __menu(void) int __msg_rt_callback(int message, void *pParam, void *user_param) { - MMMessageParamType* param = (MMMessageParamType*)pParam; + MMMessageParamType *param = (MMMessageParamType *)pParam; MMHandleType radio = (MMHandleType) user_param; int ret = 0; printf("incomming message : %d\n", message); - switch(message) - { - case MM_MESSAGE_STATE_CHANGED: - - printf("MM_MESSAGE_STATE_CHANGED: current : %d old : %d\n" - , param->state.current, param->state.previous); - break; - case MM_MESSAGE_RADIO_SCAN_START: - printf("MM_MESSAGE_RADIO_SCAN_START\n"); - break; - case MM_MESSAGE_RADIO_SCAN_INFO: - assert(param); - printf("MM_MESSAGE_RADIO_SCAN_INFO : freq : %d\n", param->radio_scan.frequency); - break; - case MM_MESSAGE_RADIO_SCAN_STOP: - printf("MM_MESSAGE_RADIO_SCAN_STOP\n"); - break; - case MM_MESSAGE_RADIO_SCAN_FINISH: - printf("MM_MESSAGE_RADIO_SCAN_FINISHED\n"); - RADIO_TEST__( mm_radio_scan_stop(radio); ) - break; - case MM_MESSAGE_RADIO_SEEK_START: + switch (message) { + case MM_MESSAGE_STATE_CHANGED: + + printf("MM_MESSAGE_STATE_CHANGED: current : %d old : %d\n" + , param->state.current, param->state.previous); + break; + case MM_MESSAGE_RADIO_SCAN_START: + printf("MM_MESSAGE_RADIO_SCAN_START\n"); + break; + case MM_MESSAGE_RADIO_SCAN_INFO: + assert(param); + printf("MM_MESSAGE_RADIO_SCAN_INFO : freq : %d\n", param->radio_scan.frequency); + break; + case MM_MESSAGE_RADIO_SCAN_STOP: + printf("MM_MESSAGE_RADIO_SCAN_STOP\n"); + break; + case MM_MESSAGE_RADIO_SCAN_FINISH: + printf("MM_MESSAGE_RADIO_SCAN_FINISHED\n"); + RADIO_TEST__(mm_radio_scan_stop(radio);) + break; + case MM_MESSAGE_RADIO_SEEK_START: printf("MM_MESSAGE_RADIO_SEEK_START\n"); break; - case MM_MESSAGE_RADIO_SEEK_FINISH: - printf("MM_MESSAGE_RADIO_SEEK_FINISHED : freq : %d\n", param->radio_scan.frequency); - break; - case MM_MESSAGE_STATE_INTERRUPTED: - printf("MM_MESSAGE_STATE_INTERRUPTED code - %d\n", param->code); - break; - case MM_MESSAGE_READY_TO_RESUME: - printf("MM_MESSAGE_READY_TO_RESUME\n"); - RADIO_TEST__( mm_radio_start(radio); ) - break; - default: - printf("ERROR : unknown message received!\n"); - break; + case MM_MESSAGE_RADIO_SEEK_FINISH: + printf("MM_MESSAGE_RADIO_SEEK_FINISHED : freq : %d\n", param->radio_scan.frequency); + break; + case MM_MESSAGE_STATE_INTERRUPTED: + printf("MM_MESSAGE_STATE_INTERRUPTED code - %d\n", param->code); + break; + case MM_MESSAGE_READY_TO_RESUME: + printf("MM_MESSAGE_READY_TO_RESUME\n"); + RADIO_TEST__(mm_radio_start(radio);) + break; + default: + printf("ERROR : unknown message received!\n"); + break; } return true; diff --git a/test/mm_radio_test_type.h b/test/mm_radio_test_type.h index ead49e9..bfa7df9 100644 --- a/test/mm_radio_test_type.h +++ b/test/mm_radio_test_type.h @@ -25,25 +25,24 @@ #include #include -typedef int (*test_function) (void); +typedef int (*test_function)(void); -typedef struct __test_item -{ +typedef struct __test_item { char menu_string[80]; - char description[128]; - test_function func; + char description[128]; + test_function func; int result; } test_item_t; #define RADIO_TEST__(x_test) \ - ret = x_test \ - if ( ! ret ) \ - { \ - printf("PASS : %s -- %s:%d\n", #x_test, __FILE__, __LINE__); \ - } \ - else \ - { \ - printf("FAIL : %s ERR-CODE : 0x%x -- %s:%d\n", #x_test, ret, __FILE__, __LINE__); \ - } + ret = x_test \ + if ( ! ret ) \ + { \ + printf("PASS : %s -- %s:%d\n", #x_test, __FILE__, __LINE__); \ + } \ + else \ + { \ + printf("FAIL : %s ERR-CODE : 0x%x -- %s:%d\n", #x_test, ret, __FILE__, __LINE__); \ + } #endif /* MM_RADIO_TEST_TYPE_H_ */ diff --git a/test/mm_radio_testsuite.c b/test/mm_radio_testsuite.c index ce7cc88..9701d75 100644 --- a/test/mm_radio_testsuite.c +++ b/test/mm_radio_testsuite.c @@ -47,8 +47,7 @@ static void __print_menu(void); static void __run_test(int key); /* list of tests*/ -test_item_t g_tests[100] = -{ +test_item_t g_tests[100] = { /* menu string : short string to be displayed to menu description : detailed description test function : a pointer to a actual test function @@ -56,57 +55,57 @@ test_item_t g_tests[100] = */ { "init test", - "check radio init function", - __test_radio_init, - 0 + "check radio init function", + __test_radio_init, + 0 }, { "listening gorealra", - "let's listen to the gorealra!", - __test_radio_listen_gorealra, - 0 + "let's listen to the gorealra!", + __test_radio_listen_gorealra, + 0 }, { "repeat_init_release", - "repeat init and release and check if it working and memory usage increment", - __test_repeat_init_release, - 0 + "repeat init and release and check if it working and memory usage increment", + __test_repeat_init_release, + 0 }, { "repeat_start_stop", - "repeat start and stop and check if it working and memory usage increment", - __test_repeat_start_stop, - 0 + "repeat start and stop and check if it working and memory usage increment", + __test_repeat_start_stop, + 0 }, { "repeat_seek", - "repeat seek and check if it working and memory usage increment", - __test_repeat_seek, - 0 + "repeat seek and check if it working and memory usage increment", + __test_repeat_seek, + 0 }, { "repeat_whole", - "repeat whole radio sequence and check if it working and memory usage increment", - __test_repeat_whole, - 0 + "repeat whole radio sequence and check if it working and memory usage increment", + __test_repeat_whole, + 0 }, { "manual api calling test", - "mapping each api to each test manu. just like other testsuite. try to reproduce the bugs with it.", - __test_manual_api_calling, - 0 + "mapping each api to each test manu. just like other testsuite. try to reproduce the bugs with it.", + __test_manual_api_calling, + 0 }, - /* add tests here*/ + /* add tests here*/ - /* NOTE : do not remove this last item */ - {"end", "", NULL, 0}, + /* NOTE : do not remove this last item */ + {"end", "", NULL, 0}, }; int g_num_of_tests = 0; @@ -121,12 +120,11 @@ int main(int argc, char **argv) do { key = getchar(); - if ( key >= '0' && key <= '9') - { - __run_test( key - '0' ); + if (key >= '0' && key <= '9') { + __run_test(key - '0'); } - }while ( key == '\n' ); - }while(key != 'q' && key == 'Q'); + } while (key == '\n'); + } while (key != 'q' && key == 'Q'); printf("radio test client finished\n"); @@ -140,9 +138,8 @@ void __print_menu(void) printf("\n\nFMRadio testing menu\n"); printf("------------------------------------------\n"); - for ( i = 0; g_tests[i].func; i++ ) - { - printf( "[%d] %s\n", i, g_tests[i].menu_string ); + for (i = 0; g_tests[i].func; i++) { + printf("[%d] %s\n", i, g_tests[i].menu_string); } printf("[q] quit\n"); @@ -157,75 +154,70 @@ void __run_test(int key) /* check index */ printf("#tests : %d key : %d\n", g_num_of_tests, key); - if ( key >= g_num_of_tests || key < 0 ) - { + if (key >= g_num_of_tests || key < 0) { printf("unassigned key has pressed : %d\n", key); return; } /* display description*/ - printf( "excuting test : %s\n", g_tests[key].menu_string ); - printf( "description : %s\n", g_tests[key].description ); + printf("excuting test : %s\n", g_tests[key].menu_string); + printf("description : %s\n", g_tests[key].description); /* calling test function*/ ret = g_tests[key].func(); g_tests[key].result = ret; - if ( ret ) - { - printf( "TEST FAILED. ret code : %d\n", g_tests[key].result); - } - else - { - printf( "TEST SUCCEDED. ret code : %d\n", g_tests[key].result); + if (ret) { + printf("TEST FAILED. ret code : %d\n", g_tests[key].result); + } else { + printf("TEST SUCCEDED. ret code : %d\n", g_tests[key].result); } } static int __msg_callback(int message, void *pParam, void *user_param) { - MMMessageParamType* param = (MMMessageParamType*)pParam; + MMMessageParamType *param = (MMMessageParamType *)pParam; MMHandleType radio = (MMHandleType) user_param; int ret = 0; printf("incomming message : %d\n", message); - switch(message) - { - case MM_MESSAGE_STATE_CHANGED: - printf("MM_MESSAGE_STATE_CHANGED: current : %d old : %d\n" - , param->state.current, param->state.previous); - break; - case MM_MESSAGE_RADIO_SCAN_START: - printf("MM_MESSAGE_RADIO_SCAN_START\n"); - break; - case MM_MESSAGE_RADIO_SCAN_INFO: - assert(param); - printf("MM_MESSAGE_RADIO_SCAN_INFO : freq : %d KHz\n", param->radio_scan.frequency); - break; - case MM_MESSAGE_RADIO_SCAN_STOP: - printf("MM_MESSAGE_RADIO_SCAN_STOP\n"); - break; - case MM_MESSAGE_RADIO_SCAN_FINISH: - printf("MM_MESSAGE_RADIO_SCAN_FINISHED\n"); - RADIO_TEST__( mm_radio_scan_stop(radio); ) - break; - case MM_MESSAGE_RADIO_SEEK_START: + switch (message) { + case MM_MESSAGE_STATE_CHANGED: + printf("MM_MESSAGE_STATE_CHANGED: current : %d old : %d\n" + , param->state.current, param->state.previous); + break; + case MM_MESSAGE_RADIO_SCAN_START: + printf("MM_MESSAGE_RADIO_SCAN_START\n"); + break; + case MM_MESSAGE_RADIO_SCAN_INFO: + assert(param); + printf("MM_MESSAGE_RADIO_SCAN_INFO : freq : %d KHz\n", param->radio_scan.frequency); + break; + case MM_MESSAGE_RADIO_SCAN_STOP: + printf("MM_MESSAGE_RADIO_SCAN_STOP\n"); + break; + case MM_MESSAGE_RADIO_SCAN_FINISH: + printf("MM_MESSAGE_RADIO_SCAN_FINISHED\n"); + RADIO_TEST__(mm_radio_scan_stop(radio);) + break; + case MM_MESSAGE_RADIO_SEEK_START: printf("MM_MESSAGE_RADIO_SEEK_START\n"); break; - case MM_MESSAGE_RADIO_SEEK_FINISH: - printf("MM_MESSAGE_RADIO_SEEK_FINISHED : freq : %d KHz\n", param->radio_scan.frequency); - break; - case MM_MESSAGE_STATE_INTERRUPTED: - printf("MM_MESSAGE_STATE_INTERRUPTED code - %d\n", param->code); - break; - case MM_MESSAGE_READY_TO_RESUME: - printf("MM_MESSAGE_READY_TO_RESUME\n"); - RADIO_TEST__( mm_radio_start(radio); ) - break; - default: - printf("ERROR : unknown message received!\n"); - break; + case MM_MESSAGE_RADIO_SEEK_FINISH: + printf("MM_MESSAGE_RADIO_SEEK_FINISHED : freq : %d KHz\n", param->radio_scan.frequency); + break; + case MM_MESSAGE_STATE_INTERRUPTED: + printf("MM_MESSAGE_STATE_INTERRUPTED code - %d\n", param->code); + break; + case MM_MESSAGE_READY_TO_RESUME: + printf("MM_MESSAGE_READY_TO_RESUME\n"); + RADIO_TEST__(mm_radio_start(radio);) + break; + default: + printf("ERROR : unknown message received!\n"); + break; } return true; @@ -239,11 +231,11 @@ int __test_radio_init(void) int ret = MM_ERROR_NONE; MMHandleType radio = 0; - RADIO_TEST__( mm_radio_create(&radio); ) - RADIO_TEST__( mm_radio_set_message_callback( radio, (MMMessageCallback)__msg_callback, (void*)radio ); ) - RADIO_TEST__( mm_radio_realize(radio); ) - RADIO_TEST__( mm_radio_unrealize(radio); ) - RADIO_TEST__( mm_radio_destroy(radio); ) + RADIO_TEST__(mm_radio_create(&radio);) + RADIO_TEST__(mm_radio_set_message_callback(radio, (MMMessageCallback)__msg_callback, (void *)radio);) + RADIO_TEST__(mm_radio_realize(radio);) + RADIO_TEST__(mm_radio_unrealize(radio);) + RADIO_TEST__(mm_radio_destroy(radio);) return ret; } @@ -254,11 +246,11 @@ int __test_radio_listen_gorealra(void) int ret = MM_ERROR_NONE; MMHandleType radio = 0; - RADIO_TEST__( mm_radio_create(&radio); ) - RADIO_TEST__( mm_radio_set_message_callback( radio, (MMMessageCallback)__msg_callback, (void*)radio ); ) - RADIO_TEST__( mm_radio_realize(radio); ) - RADIO_TEST__( mm_radio_set_frequency( radio, DEFAULT_TEST_FREQ ); ) - RADIO_TEST__( mm_radio_start(radio); ) + RADIO_TEST__(mm_radio_create(&radio);) + RADIO_TEST__(mm_radio_set_message_callback(radio, (MMMessageCallback)__msg_callback, (void *)radio);) + RADIO_TEST__(mm_radio_realize(radio);) + RADIO_TEST__(mm_radio_set_frequency(radio, DEFAULT_TEST_FREQ);) + RADIO_TEST__(mm_radio_start(radio);) return ret; } @@ -270,13 +262,12 @@ int __test_repeat_init_release(void) int cnt = 0; MMHandleType radio = 0; - while ( 1 ) - { - RADIO_TEST__( mm_radio_create(&radio); ) - RADIO_TEST__( mm_radio_set_message_callback( radio, (MMMessageCallback)__msg_callback, (void*)radio ); ) - RADIO_TEST__( mm_radio_realize(radio); ) - RADIO_TEST__( mm_radio_unrealize(radio); ) - RADIO_TEST__( mm_radio_destroy(radio); ) + while (1) { + RADIO_TEST__(mm_radio_create(&radio);) + RADIO_TEST__(mm_radio_set_message_callback(radio, (MMMessageCallback)__msg_callback, (void *)radio);) + RADIO_TEST__(mm_radio_realize(radio);) + RADIO_TEST__(mm_radio_unrealize(radio);) + RADIO_TEST__(mm_radio_destroy(radio);) cnt++; @@ -293,15 +284,14 @@ int __test_repeat_start_stop(void) int cnt = 0; MMHandleType radio = 0; - RADIO_TEST__( mm_radio_create(&radio); ) - RADIO_TEST__( mm_radio_set_message_callback( radio, (MMMessageCallback)__msg_callback, (void*)radio ); ) - RADIO_TEST__( mm_radio_realize(radio); ) - RADIO_TEST__( mm_radio_set_frequency( radio, DEFAULT_TEST_FREQ ); ) + RADIO_TEST__(mm_radio_create(&radio);) + RADIO_TEST__(mm_radio_set_message_callback(radio, (MMMessageCallback)__msg_callback, (void *)radio);) + RADIO_TEST__(mm_radio_realize(radio);) + RADIO_TEST__(mm_radio_set_frequency(radio, DEFAULT_TEST_FREQ);) - while(1) - { - RADIO_TEST__( mm_radio_start(radio); ) - RADIO_TEST__( mm_radio_stop(radio); ) + while (1) { + RADIO_TEST__(mm_radio_start(radio);) + RADIO_TEST__(mm_radio_stop(radio);) cnt++;