diff options
author | Jinkun Jang <jinkun.jang@samsung.com> | 2013-03-13 01:50:00 +0900 |
---|---|---|
committer | Jinkun Jang <jinkun.jang@samsung.com> | 2013-03-13 01:50:00 +0900 |
commit | e7a65f90ae954bfb147a2d70a626e476805372d7 (patch) | |
tree | 4dc61cd55a81177c264e94892e8b891d31e47e74 | |
parent | b3ad876ff93aa446f5404091fc38e905cdd92bfa (diff) | |
download | libmm-radio-e7a65f90ae954bfb147a2d70a626e476805372d7.tar.gz libmm-radio-e7a65f90ae954bfb147a2d70a626e476805372d7.tar.bz2 libmm-radio-e7a65f90ae954bfb147a2d70a626e476805372d7.zip |
Tizen 2.1 base
-rw-r--r-- | AUTHORS | 3 | ||||
-rw-r--r-- | LICENSE.APLv2 | 204 | ||||
-rw-r--r-- | Makefile.am | 12 | ||||
-rw-r--r-- | NOTICE | 3 | ||||
-rwxr-xr-x | autogen.sh | 7 | ||||
-rwxr-xr-x | configure.ac | 69 | ||||
-rwxr-xr-x | libmm-radio.manifest | 5 | ||||
-rw-r--r-- | mm-radio.pc.in | 11 | ||||
-rw-r--r-- | packaging/libmm-radio.spec | 63 | ||||
-rw-r--r-- | src/Makefile.am | 29 | ||||
-rw-r--r-- | src/include/mm_radio.h | 3454 | ||||
-rw-r--r-- | src/include/mm_radio_asm.h | 50 | ||||
-rw-r--r-- | src/include/mm_radio_priv.h | 234 | ||||
-rw-r--r-- | src/include/mm_radio_utils.h | 105 | ||||
-rw-r--r-- | src/mm_radio.c | 496 | ||||
-rw-r--r-- | src/mm_radio_asm.c | 229 | ||||
-rw-r--r-- | src/mm_radio_priv.c | 1491 | ||||
-rw-r--r-- | test/Makefile.am | 14 | ||||
-rw-r--r-- | test/mm_radio_rt_api_test.c | 262 | ||||
-rw-r--r-- | test/mm_radio_rt_api_test.h | 29 | ||||
-rw-r--r-- | test/mm_radio_test_type.h | 49 | ||||
-rw-r--r-- | test/mm_radio_testsuite.c | 330 |
22 files changed, 7149 insertions, 0 deletions
@@ -0,0 +1,3 @@ +JongHyuk Choi <jhchoi.choi at samsung dot com>
+YoungHwan An <younghwan_.an at samsung dot com>
+
diff --git a/LICENSE.APLv2 b/LICENSE.APLv2 new file mode 100644 index 0000000..9c13a9b --- /dev/null +++ b/LICENSE.APLv2 @@ -0,0 +1,204 @@ +Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
+
diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..f2066a6 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,12 @@ +ACLOCAL_AMFLAGS='-I m4' + +SUBDIRS = src test + +pcfiles = mm-radio.pc + +pkgconfigdir = $(libdir)/pkgconfig + +pkgconfig_DATA = $(pcfiles) + +EXTRA_DIST = $(pcfiles) + @@ -0,0 +1,3 @@ +Copyright (c) Samsung Electronics Co., Ltd. All rights reserved. +Except as noted, this software is licensed under Apache License, Version 2. +Please, see the LICENSE file for Apache License terms and conditions. diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..828897e --- /dev/null +++ b/autogen.sh @@ -0,0 +1,7 @@ +#!/bin/sh +aclocal +libtoolize +autoheader +autoconf +automake --add-missing --copy --foreign + diff --git a/configure.ac b/configure.ac new file mode 100755 index 0000000..a631a75 --- /dev/null +++ b/configure.ac @@ -0,0 +1,69 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.61) +AC_INIT(libmm-radio, 0.1.0, heechul.jeon@samsung.com) +AM_INIT_AUTOMAKE([-Wall -Werror foreign]) +AC_CONFIG_SRCDIR([src/mm_radio.c]) +AC_CONFIG_HEADER([config.h]) + +# Checks for programs. +AC_PROG_LIBTOOL +AC_PROG_CC + +# Checks for libraries. + +# Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS([fcntl.h stdlib.h sys/ioctl.h sys/time.h termios.h unistd.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_HEADER_STDBOOL +AC_C_CONST +AC_TYPE_PID_T +AC_HEADER_TIME + +# Checks for library functions. +AC_PROG_GCC_TRADITIONAL +AC_FUNC_MALLOC +AC_CHECK_FUNCS([memset strstr]) + +PKG_CHECK_MODULES(GTHREAD, gthread-2.0) +AC_SUBST(GTHREAD_CFLAGS) +AC_SUBST(GTHREAD_LIBS) + +PKG_CHECK_MODULES(MMCOMMON, mm-common) +AC_SUBST(MMCOMMON_CFLAGS) +AC_SUBST(MMCOMMON_LIBS) + +PKG_CHECK_MODULES(MMTA, mm-ta) +AC_SUBST(MMTA_CFLAGS) +AC_SUBST(MMTA_LIBS) + +PKG_CHECK_MODULES(GST, gstreamer-0.10) +AC_SUBST(GST_CFLAGS) +AC_SUBST(GST_LIBS) + +PKG_CHECK_MODULES(GSTAPP, gstreamer-app-0.10) +AC_SUBST(GSTAPP_CFLAGS) +AC_SUBST(GSTAPP_LIBS) + +PKG_CHECK_MODULES(MMSESSION, mm-session) +AC_SUBST(MMSESSION_CFLAGS) +AC_SUBST(MMSESSION_LIBS) + +PKG_CHECK_MODULES(AUDIOSESSIONMGR, audio-session-mgr) +AC_SUBST(AUDIOSESSIONMGR_CFLAGS) +AC_SUBST(AUDIOSESSIONMGR_LIBS) + +PKG_CHECK_MODULES(MMSOUND, mm-sound) +AC_SUBST(MMSOUND_CFLAGS) +AC_SUBST(MMSOUND_LIBS) + +AC_CONFIG_FILES([ + Makefile + src/Makefile + test/Makefile + mm-radio.pc +]) +AC_OUTPUT diff --git a/libmm-radio.manifest b/libmm-radio.manifest new file mode 100755 index 0000000..a76fdba --- /dev/null +++ b/libmm-radio.manifest @@ -0,0 +1,5 @@ +<manifest> + <request> + <domain name="_" /> + </request> +</manifest> diff --git a/mm-radio.pc.in b/mm-radio.pc.in new file mode 100644 index 0000000..723ca8c --- /dev/null +++ b/mm-radio.pc.in @@ -0,0 +1,11 @@ +prefix = @prefix@ +exec_prefix=@exec_prefix@ +libdir = @libdir@ +includedir = @includedir@ + +Name : mm-radio +Description : Multimedia Framwork FM Radio Library +Requires : mm-common mm-log mm-ta +Version : @VERSION@ +Libs : -L${libdir} -lmmfradio +Cflags : -I${includedir}/mmf diff --git a/packaging/libmm-radio.spec b/packaging/libmm-radio.spec new file mode 100644 index 0000000..7ff9679 --- /dev/null +++ b/packaging/libmm-radio.spec @@ -0,0 +1,63 @@ +Name: libmm-radio +Summary: Multimedia Framework Radio Library +Version: 0.2.1 +Release: 0 +Group: System/Libraries +License: Apache License, Version 2.0 +Source0: %{name}-%{version}.tar.gz +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig +BuildRequires: audio-session-manager-devel +BuildRequires: pkgconfig(mm-common) +BuildRequires: pkgconfig(mm-log) +BuildRequires: pkgconfig(mm-ta) +BuildRequires: pkgconfig(mm-session) +BuildRequires: pkgconfig(mm-sound) +BuildRequires: pkgconfig(gstreamer-0.10) +BuildRequires: pkgconfig(gstreamer-plugins-base-0.10) + +%description +Descirption: Multimedia Framework Radio Library + + +%package devel +Summary: Multimedia Framework Radio Library (DEV) +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} + +%description devel +Description: Multimedia Framework Radio Library (DEV) + +%prep +%setup -q + +%build +./autogen.sh +CFLAGS=" %{optflags} -DGST_EXT_TIME_ANALYSIS -DEXPORT_API=\"__attribute__((visibility(\\\"default\\\")))\" "; export CFLAGS; +%configure --disable-static --prefix=%{_prefix} + +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +%make_install + + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + + +%files +%manifest libmm-radio.manifest +%defattr(-,root,root,-) +%{_libdir}/libmmfradio.so.* +%{_bindir}/mm_radio_testsuite + + + +%files devel +%defattr(-,root,root,-) +%{_libdir}/libmmfradio.so +%{_libdir}/pkgconfig/mm-radio.pc +%{_includedir}/mmf/mm_radio.h diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..ac06ac6 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,29 @@ +lib_LTLIBRARIES = libmmfradio.la + +includelibmmfradiodir = $(includedir)/mmf +includelibmmfradio_HEADERS = include/mm_radio.h + +libmmfradio_la_SOURCES = mm_radio.c \ + mm_radio_priv.c \ + mm_radio_asm.c + +libmmfradio_la_CFLAGS = -I. -I./include \ + $(GTHREAD_CFLAGS) \ + $(MMCOMMON_CFLAGS) \ + $(MMTA_CFLAGS) \ + $(MMSESSION_CFLAGS) \ + $(AUDIOSESSIONMGR_CFLAGS) \ + $(MMSOUND_CFLAGS) \ + $(GST_CFLAGS) \ + $(GSTAPP_CFLAGS) \ + -DMMF_LOG_OWNER=0x200000 -DMMF_DEBUG_PREFIX=\"MM-RADIO\" \ + -DGST_EXT_TIME_ANALYSIS + +libmmfradio_la_LIBADD = $(GTHREAD_LIBS) \ + $(MMCOMMON_LIBS) \ + $(MMTA_LIBS)\ + $(MMSESSION_LIBS) \ + $(AUDIOSESSIONMGR_LIBS) \ + $(MMSOUND_LIBS) \ + $(GST_LIBS) \ + $(GSTAPP_LIBS) diff --git a/src/include/mm_radio.h b/src/include/mm_radio.h new file mode 100644 index 0000000..dba7d56 --- /dev/null +++ b/src/include/mm_radio.h @@ -0,0 +1,3454 @@ +/* + * libmm-radio + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YoungHwan An <younghwan_.an@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __MM_RADIO_H__ +#define __MM_RADIO_H__ + +#include <mm_types.h> +#include <mm_message.h> +#include <mm_error.h> + +#ifdef __cplusplus + extern "C" { +#endif + +/** + @addtogroup RADIO + @{ + + @par + This part describes the APIs with respect to play radio + + */ + + +/** + * Enumerations of radio state. + */ +typedef enum { + MM_RADIO_STATE_NULL = 1, /**< Radio is created, but not realized yet */ + MM_RADIO_STATE_READY, /**< Radio is ready to play */ + 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; + +/** + * Enumerations of seeking direction. + */ +typedef enum { + MM_RADIO_SEEK_UP, /**< Seek upward */ + MM_RADIO_SEEK_DOWN, /**< Seek downward */ + MM_RADIO_SEEK_NUM /**< Number of seeking direction */ +} MMRadioSeekDirectionType; + +/** + * Enumerations of radio region country + * Region settings are according to radio standards, not real geographic regions. + * MM_RADIO_REGION_GROUP_1 : Notrh America, South America, South Korea, Taiwan, Australia + * frequency details : 88.1 - 108MHz, 75uS de-emphasis + * + * MM_RADIO_REGION_GROUP_2 : China, Europe, Africa, Middle East, Hong Kong, India, Indonesia, Russia, Singapore + * frequency details : 87.5 - 108MHz, 50uS de-emphasis + * + * MM_RADIO_REGION_GROUP_3 : Japan alone currenlty + * frequency details : 76.1 - 89.9MHz, 50uS de-emphasis + */ +typedef enum { + MM_RADIO_REGION_GROUP_NONE = 0, /**< Region None */ + MM_RADIO_REGION_GROUP_USA, /**< Region USA group */ + MM_RADIO_REGION_GROUP_EUROPE, /**< Region EUROPE group */ + MM_RADIO_REGION_GROUP_JAPAN, /**< Region Japan group */ +} MMRadioRegionType; + +/** + * This function creates a radio handle. \n + * So, application can make radio instance and initializes it. + * + * + * @param hradio [out] Handle of radio. + * + * @return This function returns zero on success, or negative value with errors + * @pre None + * @post MM_RADIO_STATE_NULL + * @remark None + * @see mm_radio_destroy mm_radio_realize mm_radio_unrealize mm_radio_start mm_radio_stop + * @par Example + * @code +#include <stdlib.h> +#include <stdio.h> +#include <mm_radio.h> + +#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. + * + * @param hradio [in] Handle of radio. + * + * @return This function returns zero on success, or negative value with errors + * @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 + * @par Example + * @code +#include <stdlib.h> +#include <stdio.h> +#include <mm_radio.h> + +#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); + +/** + * This function opens radio device and ready to tune. \n + * + * @param hradio [in] Handle of radio. + * + * @return This function returns zero on success, or negative value with errors + * @pre MM_RADIO_STATE_NULL + * @post MM_RADIO_STATE_READY + * @remark None + * @see mm_radio_create mm_radio_destroy mm_radio_unrealize mm_radio_start mm_radio_stop + * @par Example + * @code +#include <stdlib.h> +#include <stdio.h> +#include <mm_radio.h> + +#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. + * + * @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_NULL + * @remark None + * @see mm_radio_create mm_radio_destroy mm_radio_realize mm_radio_start mm_radio_stop + * @par Example + * @code +#include <stdlib.h> +#include <stdio.h> +#include <mm_radio.h> + +#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); + +/** + * This function sets the callback function for receiving messages from radio. + * + * @param hradio [in] Handle of radio. + * @param callback [in] Message callback function. + * @param user_param [in] User parameter which is passed to callback function. + * + * @return This function returns zero on success, or negative value with errors + * @pre None + * @post None + * @remark None + * @see + * @par Example + * @code +#include <stdlib.h> +#include <stdio.h> +#include <mm_radio.h> + +#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); + +/** + * This function gets the current state of radio. + * + * @param hradio [in] Handle of radio. + * @param state [out] Current state of radio. + * + * @return This function returns zero on success, or negative value with errors + * @pre None + * @post None + * @remark None + * @see + * @par Example + * @code +#include <stdlib.h> +#include <stdio.h> +#include <mm_radio.h> + +#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); + +/** + * This function is to start playing radio. + * + * @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_PLAYING + * @remark None + * @see mm_radio_create mm_radio_destroy mm_radio_realize mm_radio_unrealize mm_radio_stop + * @par Example + * @code +#include <stdlib.h> +#include <stdio.h> +#include <mm_radio.h> + +#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_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 <stdlib.h> +#include <stdio.h> +#include <mm_radio.h> + +#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 seeks the effective frequency of radio. The application get a valid frequency from current value. \n + * And, it can select direction to seek. + * 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. + * One is to seek continually in the same direction. The other is to set previous frequency. + * + * @param hradio [in] Handle of radio. + * @param direction [in] Seeking direction. + * + * @return This function returns zero on success, or negative value with errors + * @pre MM_RADIO_STATE_PLAYING + * @post MM_RADIO_STATE_PLAYING + * @remark None + * @see MM_MESSAGE_RADIO_SEEK_START MM_MESSAGE_RADIO_SEEK_FINISH + * @par Example + * @code +#include <stdlib.h> +#include <stdio.h> +#include <mm_radio.h> + +#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); + +/** + * This function sets the radio frequency with the desired one. + * + * @param hradio [in] Handle of radio. + * @param freq [in] Frequency to set. + * + * @return This function returns zero on success, or negative value with errors + * @pre MM_RADIO_STATE_READY, MM_RADIO_STATE_PLAYING + * @post MM_RADIO_STATE_READY, MM_RADIO_STATE_PLAYING + * @remark None + * @see mm_radio_get_frequency + * @par Example + * @code +#include <stdlib.h> +#include <stdio.h> +#include <mm_radio.h> + +#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); + +/** + * This function gets the current frequency of radio. + * + * @param hradio [in] Handle of radio. + * @param pFreq [out] Current frequency. + * + * @return This function returns zero on success, or negative value with errors + * @pre MM_RADIO_STATE_READY, MM_RADIO_STATE_PLAYING + * @post MM_RADIO_STATE_READY, MM_RADIO_STATE_PLAYING + * @remark None + * @see mm_radio_set_frequency + * @par Example + * @code +#include <stdlib.h> +#include <stdio.h> +#include <mm_radio.h> + +#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); + +/** + * 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. + * + * @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 + * @remark None + * @see mm_radio_scan_stop + * @par Example + * @code +#include <stdlib.h> +#include <stdio.h> +#include <mm_radio.h> + +#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. + * + * @param hradio [in] Handle of radio. + * + * @return This function returns zero on success, or negative value with errors + * @pre MM_RADIO_STATE_SCANNING + * @post MM_RADIO_STATE_READY + * @remark None + * @see mm_radio_scan_start + * @par Example + * @code +#include <stdlib.h> +#include <stdio.h> +#include <mm_radio.h> + +#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); + +/** + * This function is to mute/unmute radio output. + * + * @param hradio [in] Handle of radio. + * @param muted [in] 0: unmute 1: mute + * + * @return This function returns zero on success, or negative value with errors + * @pre None + * @post None + * @remark None + * @see + * @par Example + * @code +#include <stdlib.h> +#include <stdio.h> +#include <mm_radio.h> + +#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); +/** + * This function is get strength of radio signal. + * + * @param hradio [in] Handle of radio. + * @param value [in] signal strength + * + * @return This function returns zero on success, or negative value with errors + * @pre None + * @post None + * @remark None + * @see + * @par Example + * @code +#include <stdlib.h> +#include <stdio.h> +#include <mm_radio.h> + +#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); + +/** + * This function is to get type of radio region. + * + * @param hradio [in] Handle of radio. + * @param type [out] type of current region + * + * @return This function returns zero on success, or negative value with errors + * @pre None + * @post None + * @remark None + * @see mm_radio_get_region_frequency_range() + */ +int mm_radio_get_region_type(MMHandleType hradio, MMRadioRegionType *type); + +/** + * This function is to get range of radio frequency. + * + * @param hradio [in] Handle of radio. + * @param min [out] min frequency value + * @param max [out] max frequency value + * + * @return This function returns zero on success, or negative value with errors + * @pre None + * @post None + * @remark The unit of frequency is KHz. + * @see mm_radio_get_region_type() + */ +int mm_radio_get_region_frequency_range(MMHandleType hradio, unsigned int *min, unsigned int *max); + +/** + @} + */ + + +#ifdef __cplusplus + } +#endif + +#endif /* __MM_RADIO_H__ */ diff --git a/src/include/mm_radio_asm.h b/src/include/mm_radio_asm.h new file mode 100644 index 0000000..c8d1c93 --- /dev/null +++ b/src/include/mm_radio_asm.h @@ -0,0 +1,50 @@ +/* + * libmm-radio + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YoungHwan An <younghwan_.an@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef MM_RADIO_ASM_H_ +#define MM_RADIO_ASM_H_ + +#include <mm_types.h> +#include <mm_error.h> + +#include <mm_session.h> +#include <mm_session_private.h> +#include <audio-session-manager.h> + +enum { + MMRADIO_ASM_CB_NONE, + MMRADIO_ASM_CB_POSTMSG, + MMRADIO_ASM_CB_SKIP_POSTMSG +}; +typedef struct { + int handle; + int pid; + int by_asm_cb; + int event_src; + ASM_sound_states_t state; +} MMRadioASM; + +/* 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); + +#endif /* MM_RADIO_ASM_H_ */ diff --git a/src/include/mm_radio_priv.h b/src/include/mm_radio_priv.h new file mode 100644 index 0000000..04c14b8 --- /dev/null +++ b/src/include/mm_radio_priv.h @@ -0,0 +1,234 @@ +/* + * libmm-radio + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YoungHwan An <younghwan_.an@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __MM_Radio_INTERNAL_H__ +#define __MM_Radio_INTERNAL_H__ + +/*=========================================================================================== + INCLUDE FILES +========================================================================================== */ +#include <stdio.h> +#include <stdbool.h> +#include <unistd.h> +#include <malloc.h> +#include <pthread.h> +#include <signal.h> + +#include <mm_types.h> +#include <mm_message.h> + +#include "mm_radio_asm.h" +#include "mm_radio.h" +#include "mm_radio_utils.h" +#include <linux/videodev2.h> + +#include <gst/gst.h> +#include <gst/gstbuffer.h> + +#ifdef __cplusplus + extern "C" { +#endif + +/*=========================================================================================== + GLOBAL DEFINITIONS AND DECLARATIONS FOR MODULE +========================================================================================== */ + +/*--------------------------------------------------------------------------- + GLOBAL #defines: +---------------------------------------------------------------------------*/ +#define SAMPLEDELAY 15000 + +/* si470x dependent define */ +#define SYSCONFIG1 4 /* System Configuration 1 */ +#define SYSCONFIG1_RDS 0x1000 /* bits 12..12: RDS Enable */ +#define SYSCONFIG1_RDS_OFFSET 12 /* bits 12..12: RDS Enable Offset */ + +#define SYSCONFIG2 5 /* System Configuration 2 */ +#define SYSCONFIG2_SEEKTH 0xff00 /* bits 15..08: RSSI Seek Threshold */ +#define SYSCONFIG2_SEEKTH_OFFSET 8 /* bits 15..08: RSSI Seek Threshold Offset */ + +#define SYSCONFIG3 6 /* System Configuration 3 */ +#define SYSCONFIG3_SKSNR 0x00f0 /* bits 07..04: Seek SNR Threshold */ +#define SYSCONFIG3_SKCNT 0x000f /* bits 03..00: Seek FM Impulse Detection Threshold */ +#define SYSCONFIG3_SKSNR_OFFSET 4 /* bits 07..04: Seek SNR Threshold Offset */ +#define SYSCONFIG3_SKCNT_OFFSET 0 /* bits 03..00: Seek FM Impulse Detection Threshold Offset */ + +#define DEFAULT_CHIP_MODEL "radio-si470x" + +/*--------------------------------------------------------------------------- + GLOBAL CONSTANT DEFINITIONS: +---------------------------------------------------------------------------*/ +typedef enum +{ + MMRADIO_COMMAND_CREATE = 0, + MMRADIO_COMMAND_DESTROY, + MMRADIO_COMMAND_REALIZE, + MMRADIO_COMMAND_UNREALIZE, + MMRADIO_COMMAND_START, + MMRADIO_COMMAND_STOP, + MMRADIO_COMMAND_START_SCAN, + MMRADIO_COMMAND_STOP_SCAN, + MMRADIO_COMMAND_SET_FREQ, + MMRADIO_COMMAND_GET_FREQ, + MMRADIO_COMMAND_MUTE, + MMRADIO_COMMAND_UNMUTE, + MMRADIO_COMMAND_SEEK, + MMRADIO_COMMAND_SET_REGION, + MMRADIO_COMMAND_GET_REGION, + MMRADIO_COMMAND_NUM +} MMRadioCommand; + +/* max and mix frequency types, KHz */ +typedef enum +{ + MM_RADIO_FREQ_NONE = 0, + /* min band types */ + MM_RADIO_FREQ_MIN_76100_KHZ = 76100, + MM_RADIO_FREQ_MIN_87500_KHZ = 87500, + MM_RADIO_FREQ_MIN_88100_KHZ = 88100, + /* max band types */ + MM_RADIO_FREQ_MAX_89900_KHZ = 89900, + MM_RADIO_FREQ_MAX_108000_KHZ = 108000, +}MMRadioFreqTypes; + +/* de-emphasis types */ +typedef enum +{ + MM_RADIO_DEEMPHASIS_NONE = 0, + MM_RADIO_DEEMPHASIS_50_US, + MM_RADIO_DEEMPHASIS_75_US, +}MMRadioDeemphasis; + +/* radio region settings */ +typedef struct +{ + MMRadioRegionType country; + MMRadioDeemphasis deemphasis; // unit : us + MMRadioFreqTypes band_min; // <- freq. range, unit : KHz + MMRadioFreqTypes band_max; // -> + //int channel_spacing; // TBD +}MMRadioRegion_t; + +/*--------------------------------------------------------------------------- + GLOBAL DATA TYPE DEFINITIONS: +---------------------------------------------------------------------------*/ +#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 { + /* radio state */ + int current_state; + int old_state; + int pending_state; + + int cmd; + + /* command lock */ + pthread_mutex_t cmd_lock; + + /* radio attributes */ + MMHandleType* attrs; + + /* message callback */ + MMMessageCallback msg_cb; + void* msg_cb_param; + + /* radio device fd */ + int radio_fd; + + /* 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; + + /* scan */ + pthread_t scan_thread; + bool stop_scan; + + /* seek */ + pthread_t seek_thread; + int prev_seek_freq; + MMRadioSeekDirectionType seek_direction; + + /* ASM */ + MMRadioASM sm; + + int freq; +#ifdef USE_GST_PIPELINE + mm_radio_gstreamer_s* pGstreamer_s; +#endif + + /* region settings */ + MMRadioRegion_t region_setting; +} mm_radio_t; + +/*=========================================================================================== + GLOBAL FUNCTION PROTOTYPES +========================================================================================== */ +int _mmradio_create_radio(mm_radio_t* radio); +int _mmradio_destroy(mm_radio_t* radio); +int _mmradio_realize(mm_radio_t* radio); +int _mmradio_unrealize(mm_radio_t* radio); +int _mmradio_set_message_callback(mm_radio_t* radio, MMMessageCallback callback, void *user_param); +int _mmradio_get_state(mm_radio_t* radio, int* pState); +int _mmradio_set_frequency(mm_radio_t* radio, int freq); +int _mmradio_get_frequency(mm_radio_t* radio, int* pFreq); +int _mmradio_mute(mm_radio_t* radio); +int _mmradio_unmute(mm_radio_t* radio); +int _mmradio_start(mm_radio_t* radio); +int _mmradio_stop(mm_radio_t* radio); +int _mmradio_seek(mm_radio_t* radio, MMRadioSeekDirectionType direction); +int _mmradio_start_scan(mm_radio_t* radio); +int _mmradio_stop_scan(mm_radio_t* radio); +#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 _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 +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_utils.h b/src/include/mm_radio_utils.h new file mode 100644 index 0000000..13c3765 --- /dev/null +++ b/src/include/mm_radio_utils.h @@ -0,0 +1,105 @@ +/* + * libmm-radio + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YoungHwan An <younghwan_.an@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __MM_RADIO_UTILS_H__ +#define __MM_RADIO_UTILS_H__ + +#include <assert.h> +#include <mm_types.h> +#include <mm_error.h> +#include <mm_message.h> + +/* radio log */ +#define MMRADIO_LOG_FENTER debug_fenter +#define MMRADIO_LOG_FLEAVE debug_fleave +#define MMRADIO_LOG_DEBUG debug_log +#define MMRADIO_LOG_ERROR debug_error +#define MMRADIO_LOG_WARNING debug_warning +#define MMRADIO_LOG_CRITICAL debug_critical + +/* general */ +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +#endif + +#define MMRADIO_MAX_INT (2147483647) + +#define MMRADIO_FREEIF(x) \ +if ( x ) \ + free( x ); \ +x = NULL; + +#define MMRADIO_CHECK_INSTANCE( x_radio ) \ +if ( ! x_radio ) \ +{ \ + debug_error("radio instance is NULL\n"); \ + return MM_ERROR_RADIO_NOT_INITIALIZED; \ +} + +#define MMRADIO_CHECK_DEVICE_STATE( x_radio ) \ +if ( x_radio->radio_fd < 0 ) \ +{ \ + debug_error("not available radio device\n"); \ + return MM_ERROR_RADIO_NOT_INITIALIZED;\ +} + +/* command locking for multithreading */ +#define MMRADIO_CMD_LOCK(x_radio) pthread_mutex_lock( &((mm_radio_t*)x_radio)->cmd_lock ) +#define MMRADIO_CMD_UNLOCK(x_radio) pthread_mutex_unlock( &((mm_radio_t*)x_radio)->cmd_lock ) + +/* message posting */ +#define MMRADIO_POST_MSG( x_radio, x_msgtype, x_msg_param ) \ +debug_log("posting %s to application\n", #x_msgtype); \ +__mmradio_post_message(x_radio, x_msgtype, x_msg_param); + +/* setting radio state */ +#define MMRADIO_SET_STATE( x_radio, x_state ) \ +debug_log("setting mm-radio state to %d\n", x_state); \ +__mmradio_set_state(x_radio, x_state); + +/* state */ +#define MMRADIO_CHECK_STATE_RETURN_IF_FAIL( x_radio, x_command ) \ +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: \ + return MM_ERROR_RADIO_INVALID_STATE; \ + break; \ + /* NOTE : for robustness of mmfw. we won't treat it as an error */ \ + case MM_ERROR_RADIO_NO_OP: \ + return MM_ERROR_NONE; \ + 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);\ + return x_ret; \ + } \ +} while( 0 ) ; + +#endif + diff --git a/src/mm_radio.c b/src/mm_radio.c new file mode 100644 index 0000000..8370451 --- /dev/null +++ b/src/mm_radio.c @@ -0,0 +1,496 @@ +/* + * libmm-radio + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YoungHwan An <younghwan_.an@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/*=========================================================================================== +| | +| INCLUDE FILES | +| | +========================================================================================== */ + +#include <string.h> +#include "mm_radio.h" +#include "mm_radio_priv.h" +#include "mm_radio_utils.h" +#include <mm_types.h> +#include <mm_message.h> +#include "mm_debug.h" +#include <mm_ta.h> + +/*=========================================================================================== +| | +| LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE | +| | +========================================================================================== */ + +/*--------------------------------------------------------------------------- +| GLOBAL CONSTANT DEFINITIONS: | +---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- +| IMPORTED VARIABLE DECLARATIONS: | +---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- +| IMPORTED FUNCTION DECLARATIONS: | +---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- +| LOCAL #defines: | +---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- +| LOCAL CONSTANT DEFINITIONS: | +---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- +| LOCAL DATA TYPE DEFINITIONS: | +---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- +| GLOBAL VARIABLE DEFINITIONS: | +---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- +| LOCAL VARIABLE DEFINITIONS: | +---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- +| LOCAL FUNCTION PROTOTYPES: | +---------------------------------------------------------------------------*/ + +/*=========================================================================== +| | +| FUNCTION DEFINITIONS | +| | +========================================================================== */ + +int mm_radio_create(MMHandleType *hradio) +{ + int result = MM_ERROR_NONE; + mm_radio_t* new_radio = NULL; + + MMRADIO_LOG_FENTER(); + + return_val_if_fail(hradio, MM_ERROR_RADIO_NOT_INITIALIZED); + + MMTA_INIT(); + + /* alloc radio structure */ + 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 ); + + if(result != MM_ERROR_NONE) + goto ERROR; + + *hradio = (MMHandleType)new_radio; + + MMRADIO_LOG_FLEAVE(); + + return result; + +ERROR: + + if ( new_radio ) + { + MMRADIO_FREEIF( new_radio ); + } + + *hradio = (MMHandleType)0; + + MMRADIO_LOG_FLEAVE(); + + /* FIXIT : need to specify more error case */ + return MM_ERROR_RADIO_NO_FREE_SPACE; +} + +int mm_radio_destroy(MMHandleType hradio) +{ + int result = MM_ERROR_NONE; + mm_radio_t* radio = (mm_radio_t*)hradio; + + MMRADIO_LOG_FENTER(); + + return_val_if_fail(radio, MM_ERROR_RADIO_NOT_INITIALIZED); + + result = _mmradio_destroy( radio ); + + if ( result != MM_ERROR_NONE ) + { + debug_error("failed to destroy radio\n"); + } + + /* free radio */ + MMRADIO_FREEIF( radio ); + + MMTA_ACUM_ITEM_SHOW_RESULT_TO(MMTA_SHOW_FILE); + //MMTA_ACUM_ITEM_SHOW_RESULT_TO(MMTA_SHOW_STDOUT); + + MMTA_RELEASE(); + + MMRADIO_LOG_FLEAVE(); + + return result; +} + +int mm_radio_realize(MMHandleType hradio) +{ + int result = MM_ERROR_NONE; + 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 ); + + __ta__("[KPI] initialize media radio service", + result = _mmradio_realize( radio ); + ) + + MMRADIO_CMD_UNLOCK( radio ); + + MMRADIO_LOG_FLEAVE(); + + return result; +} + +int mm_radio_unrealize(MMHandleType hradio) +{ + int result = MM_ERROR_NONE; + 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 ); + + __ta__("[KPI] cleanup media radio service", + result = _mmradio_unrealize( radio ); + ) + + MMRADIO_CMD_UNLOCK( radio ); + + MMRADIO_LOG_FLEAVE(); + + return result; +} + +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; + + MMRADIO_LOG_FENTER(); + + return_val_if_fail(radio, MM_ERROR_RADIO_NOT_INITIALIZED); + + MMRADIO_CMD_LOCK( radio ); + + result = _mmradio_set_message_callback( radio, callback, user_param ); + + MMRADIO_CMD_UNLOCK( radio ); + + MMRADIO_LOG_FLEAVE(); + + return result; +} + +int mm_radio_get_state(MMHandleType hradio, MMRadioStateType* pState) +{ + int result = MM_ERROR_NONE; + mm_radio_t* radio = (mm_radio_t*)hradio; + int state = 0; + + MMRADIO_LOG_FENTER(); + + return_val_if_fail(radio, MM_ERROR_RADIO_NOT_INITIALIZED); + return_val_if_fail(pState, MM_ERROR_COMMON_INVALID_ARGUMENT); + + MMRADIO_CMD_LOCK( radio ); + + result = _mmradio_get_state( radio, &state ); + + *pState = state; + + MMRADIO_CMD_UNLOCK( radio ); + + MMRADIO_LOG_FLEAVE(); + + return result; +} + +int mm_radio_start(MMHandleType hradio) +{ + int result = MM_ERROR_NONE; + 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 ); + + MMTA_ACUM_ITEM_BEGIN("[KPI] start media radio service", false); + result = _mmradio_start( radio ); + + MMRADIO_CMD_UNLOCK( radio ); + + MMRADIO_LOG_FLEAVE(); + + return result; +} + +int mm_radio_stop(MMHandleType hradio) +{ + int result = MM_ERROR_NONE; + 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 ); + + __ta__("[KPI] stop media radio service", + result = _mmradio_stop( radio ); + ) + + MMRADIO_CMD_UNLOCK( radio ); + + MMRADIO_LOG_FLEAVE(); + + return result; +} + +int mm_radio_seek(MMHandleType hradio, MMRadioSeekDirectionType direction) +{ + int result = MM_ERROR_NONE; + 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 ); + + result = _mmradio_seek( radio, direction ); + + MMRADIO_CMD_UNLOCK( radio ); + + MMRADIO_LOG_FLEAVE(); + + return result; +} + +int mm_radio_set_frequency(MMHandleType hradio, int freq) +{ + int result = MM_ERROR_NONE; + 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 ); + + result = _mmradio_set_frequency( radio, freq ); + + MMRADIO_CMD_UNLOCK( radio ); + + MMRADIO_LOG_FLEAVE(); + + return result; +} + +int mm_radio_get_frequency(MMHandleType hradio, int* pFreq) +{ + int result = MM_ERROR_NONE; + mm_radio_t* radio = (mm_radio_t*)hradio; + int freq = 0; + + MMRADIO_LOG_FENTER(); + + return_val_if_fail(radio, MM_ERROR_RADIO_NOT_INITIALIZED); + return_val_if_fail(pFreq, MM_ERROR_INVALID_ARGUMENT); + + MMRADIO_CMD_LOCK( radio ); + + result = _mmradio_get_frequency( radio, &freq ); + + *pFreq = freq; + + MMRADIO_CMD_UNLOCK( radio ); + + MMRADIO_LOG_FLEAVE(); + + return result; +} + +int mm_radio_scan_start(MMHandleType hradio) +{ + int result = MM_ERROR_NONE; + 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 ); + + result = _mmradio_start_scan( radio ); + + MMRADIO_CMD_UNLOCK( radio ); + + MMRADIO_LOG_FLEAVE(); + + return result; +} + +int mm_radio_scan_stop(MMHandleType hradio) +{ + int result = MM_ERROR_NONE; + 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 ); + + result = _mmradio_stop_scan( radio ); + + MMRADIO_CMD_UNLOCK( radio ); + + MMRADIO_LOG_FLEAVE(); + + return result; +} + +int mm_radio_set_mute(MMHandleType hradio, bool muted) +{ + int result = MM_ERROR_NONE; + 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); + + if (muted) + { + result = _mmradio_mute(radio); + } + else + { + result = _mmradio_unmute(radio); + } + + MMRADIO_CMD_UNLOCK(radio); + + MMRADIO_LOG_FLEAVE(); + + return result; +} + +int mm_radio_get_signal_strength(MMHandleType hradio, int *value) +{ + return_val_if_fail(hradio, MM_ERROR_RADIO_NOT_INITIALIZED); + return_val_if_fail(value, MM_ERROR_INVALID_ARGUMENT); + + MMRADIO_LOG_FENTER(); + + int ret = MM_ERROR_NONE; + + mm_radio_t* radio = (mm_radio_t*)hradio; + + MMRADIO_CMD_LOCK( radio ); + + 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; + + MMRADIO_CMD_UNLOCK( radio ); + + MMRADIO_LOG_DEBUG("signal strength = %d\n", *value); + MMRADIO_LOG_FLEAVE(); + + return ret; +} + +int mm_radio_get_region_type(MMHandleType hradio, MMRadioRegionType *type) +{ + MMRADIO_LOG_FENTER(); + return_val_if_fail(hradio, MM_ERROR_RADIO_NOT_INITIALIZED); + return_val_if_fail(type, MM_ERROR_INVALID_ARGUMENT); + + int result = MM_ERROR_NONE; + mm_radio_t* radio = (mm_radio_t*)hradio; + MMRadioRegionType cur_type = MM_RADIO_REGION_GROUP_NONE; + + result = _mmradio_get_region_type(radio, &cur_type); + + if (result == MM_ERROR_NONE) + *type = cur_type; + + MMRADIO_LOG_FLEAVE(); + return result; +} + +int mm_radio_get_region_frequency_range(MMHandleType hradio, unsigned int *min, unsigned int*max) +{ + MMRADIO_LOG_FENTER(); + + return_val_if_fail(hradio, MM_ERROR_RADIO_NOT_INITIALIZED); + return_val_if_fail(min && max, MM_ERROR_INVALID_ARGUMENT); + + int result = MM_ERROR_NONE; + 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) + { + *min = min_freq; + *max = max_freq; + } + + MMRADIO_LOG_FLEAVE(); + return result; +} + diff --git a/src/mm_radio_asm.c b/src/mm_radio_asm.c new file mode 100644 index 0000000..8f3d59e --- /dev/null +++ b/src/mm_radio_asm.c @@ -0,0 +1,229 @@ +/* + * libmm-radio + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YoungHwan An <younghwan_.an@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <assert.h> +#include <mm_debug.h> +#include "mm_radio_asm.h" +#include "mm_radio_utils.h" + +static ASM_sound_events_t __mmradio_asm_get_event_type(int type); + +int mmradio_asm_register(MMRadioASM* sm, ASM_sound_cb_t callback, void* param) +{ + /* read mm-session type */ + int sessionType = MM_SESSION_TYPE_SHARE; + int errorcode = MM_ERROR_NONE; + int asm_handle = -1; + int event_type = ASM_EVENT_NONE; + int pid = -1; + + MMRADIO_LOG_FENTER(); + + if ( ! sm ) + { + MMRADIO_LOG_ERROR("invalid session handle\n"); + return MM_ERROR_RADIO_NOT_INITIALIZED; + } + + /* read session type */ + errorcode = _mm_session_util_read_type(-1, &sessionType); + if ( errorcode ) + { + MMRADIO_LOG_WARNING("Read MMSession Type failed. use default \"exclusive\" type\n"); + sessionType = MM_SESSION_TYPE_EXCLUSIVE; + + /* init session */ + errorcode = mm_session_init(sessionType); + if ( errorcode ) + { + MMRADIO_LOG_CRITICAL("mm_session_init() failed\n"); + return errorcode; + } + } + + /* check if it's CALL */ + if ( sessionType == MM_SESSION_TYPE_CALL || sessionType == MM_SESSION_TYPE_VIDEOCALL) + { + MMRADIO_LOG_DEBUG("session type is VOICE or VIDEO CALL (%d)\n", sessionType); + return MM_ERROR_NONE; + } + + /* interpret session type */ + event_type = __mmradio_asm_get_event_type(sessionType); + + /* check if it's running on the media_server */ + 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 + { + 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)) + { + MMRADIO_LOG_CRITICAL("ASM_register_sound() failed\n"); + return errorcode; + } + + /* now succeded to register our callback. take result */ + sm->handle = asm_handle; + sm->state = ASM_STATE_NONE; + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; +} + +int mmradio_asm_deregister(MMRadioASM* sm) +{ + int sessionType = MM_SESSION_TYPE_SHARE; + int event_type = ASM_EVENT_NONE; + int errorcode = 0; + + MMRADIO_LOG_FENTER(); + + if ( ! sm ) + { + MMRADIO_LOG_ERROR("invalid session handle\n"); + return MM_ERROR_RADIO_NOT_INITIALIZED; + } + + /* read session type */ + errorcode = _mm_session_util_read_type(-1, &sessionType); + if ( errorcode ) + { + MMRADIO_LOG_ERROR("MMSessionReadType Fail %s\n",__func__); + return MM_ERROR_POLICY_INTERNAL; + } + + /* check if it's CALL */ + if ( sessionType == MM_SESSION_TYPE_CALL || sessionType == MM_SESSION_TYPE_VIDEOCALL) + { + MMRADIO_LOG_DEBUG("session type is VOICE or VIDEO CALL (%d)\n", sessionType); + return MM_ERROR_NONE; + } + + /* interpret session type */ + event_type = __mmradio_asm_get_event_type(sessionType); + + if( ! ASM_unregister_sound( sm->handle, event_type, &errorcode) ) + { + MMRADIO_LOG_ERROR("Unregister sound failed 0x%X\n", errorcode); + return MM_ERROR_POLICY_INTERNAL; + } + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; +} + +int mmradio_asm_set_state(MMRadioASM* sm, ASM_sound_states_t state, ASM_resource_t resource) +{ + int sessionType = MM_SESSION_TYPE_SHARE; + int event_type = ASM_EVENT_NONE; + int errorcode = 0; + + MMRADIO_LOG_FENTER(); + + if ( ! sm ) + { + MMRADIO_LOG_ERROR("invalid session handle\n"); + return MM_ERROR_RADIO_NOT_INITIALIZED; + } + + /* read session type */ + errorcode = _mm_session_util_read_type(-1, &sessionType); + if ( errorcode ) + { + MMRADIO_LOG_ERROR("MMSessionReadType Fail\n"); + return MM_ERROR_POLICY_INTERNAL; + } + + /* check if it's CALL */ + if ( sessionType == MM_SESSION_TYPE_CALL || sessionType == MM_SESSION_TYPE_VIDEOCALL ) + { + MMRADIO_LOG_DEBUG("session type is VOICE or VIDEO CALL (%d)\n", sessionType); + return MM_ERROR_NONE; + } + + if ( sm->by_asm_cb == MMRADIO_ASM_CB_NONE ) //|| sm->state == ASM_STATE_PLAYING ) + { + int ret = 0; + + event_type = __mmradio_asm_get_event_type(sessionType); + + 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 + { + sm->by_asm_cb = MMRADIO_ASM_CB_NONE; + sm->state = state; + } + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; +} + + +ASM_sound_events_t __mmradio_asm_get_event_type(int type) +{ + int event_type = ASM_EVENT_NONE; + + MMRADIO_LOG_FENTER(); + + /* interpret session type */ + switch(type) + { + case MM_SESSION_TYPE_SHARE: + event_type = ASM_EVENT_SHARE_FMRADIO; + break; + + case MM_SESSION_TYPE_EXCLUSIVE: + event_type = ASM_EVENT_EXCLUSIVE_FMRADIO; + break; + + case MM_SESSION_TYPE_ALARM: + event_type = ASM_EVENT_ALARM; + break; + + case MM_SESSION_TYPE_NOTIFY: + case MM_SESSION_TYPE_CALL: + case MM_SESSION_TYPE_VIDEOCALL: + default: + MMRADIO_LOG_CRITICAL("unexpected case! (%d)\n", type); + assert(0); + } + + MMRADIO_LOG_FLEAVE(); + + return event_type; +} diff --git a/src/mm_radio_priv.c b/src/mm_radio_priv.c new file mode 100644 index 0000000..eca66b2 --- /dev/null +++ b/src/mm_radio_priv.c @@ -0,0 +1,1491 @@ +/* + * libmm-radio + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YoungHwan An <younghwan_.an@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/*=========================================================================================== +| | +| INCLUDE FILES | +| | +========================================================================================== */ +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <unistd.h> +#include <errno.h> +#include <mm_sound.h> +#include <mm_ta.h> + +#include <mm_error.h> +#include <mm_debug.h> +#include <mm_message.h> + +#include "mm_radio_priv.h" + +/*=========================================================================================== + 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_USA + +/*--------------------------------------------------------------------------- + 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. + }, + { /* 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, + }, +}; +/*--------------------------------------------------------------------------- + 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); + +/*=========================================================================== + 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 ret = MM_ERROR_NONE; + 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; + } + } + } + + /* chech device is opened or not. if it's not ready, skip to apply region to device now*/ + if (radio->radio_fd < 0) + { + MMRADIO_LOG_DEBUG("not opened device. just updating region info. \n"); + return MM_ERROR_NONE; + } + + MMRADIO_LOG_DEBUG("setting region - country: %d, de-emphasis: %d, band range: %d ~ %d KHz\n", + radio->region_setting.country, radio->region_setting.deemphasis, radio->region_setting.band_min, radio->region_setting.band_max); + + /* set de-emphsasis to device */ + ret = __mmradio_set_deemphasis(radio); + + MMRADIO_CHECK_RETURN_IF_FAIL(ret, "set de-emphasis"); + + /* set band range to device */ + ret = __mmradio_set_band_range(radio); + + MMRADIO_CHECK_RETURN_IF_FAIL(ret, "set band range"); + + MMRADIO_LOG_FLEAVE(); + + return ret; +} + +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)); + + /* 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 ); + + /* register to ASM */ + ret = mmradio_asm_register(&radio->sm, __mmradio_asm_callback, (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_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 ); + + /* open radio device */ + if(radio->radio_fd == -1) + { + MMRadioRegionType region = MM_RADIO_REGION_GROUP_NONE; + bool update = false; + + /* open device */ + radio->radio_fd = open(DEFAULT_DEVICE, O_RDONLY); + if (radio->radio_fd < 0) + { + MMRADIO_LOG_ERROR("failed to open radio device[%s] because of %s(%d)\n", + DEFAULT_DEVICE, strerror(errno), errno); + + /* check error */ + switch (errno) + { + case ENOENT: + return MM_ERROR_RADIO_DEVICE_NOT_FOUND; + case EACCES: + return MM_ERROR_RADIO_PERMISSION_DENIED; + default: + return MM_ERROR_RADIO_DEVICE_NOT_OPENED; + } + } + MMRADIO_LOG_DEBUG("radio device fd : %d\n", radio->radio_fd); + + /* query radio device capabilities. */ + if (ioctl(radio->radio_fd, VIDIOC_QUERYCAP, &(radio->vc)) < 0) + { + MMRADIO_LOG_ERROR("VIDIOC_QUERYCAP failed!\n"); + goto error; + } + + if ( ! ( radio->vc.capabilities & V4L2_CAP_TUNER) ) + { + MMRADIO_LOG_ERROR("this system can't support fm-radio!\n"); + goto error; + } + + /* set tuner audio mode */ + ioctl(radio->radio_fd, VIDIOC_G_TUNER, &(radio->vt)); + + if ( ! ( (radio->vt).capability & V4L2_TUNER_CAP_STEREO) ) + { + MMRADIO_LOG_ERROR("this system can support mono!\n"); + (radio->vt).audmode = V4L2_TUNER_MODE_MONO; + } + else + { + (radio->vt).audmode = V4L2_TUNER_MODE_STEREO; + } + + /* set tuner index. Must be 0. */ + (radio->vt).index = TUNER_INDEX; + ioctl(radio->radio_fd, VIDIOC_S_TUNER, &(radio->vt)); + + /* check region country type if it's updated or not */ + if ( radio->region_setting.country == MM_RADIO_REGION_GROUP_NONE) + { + /* not initialized yet. set it with default region */ + region = RADIO_DEFAULT_REGION; + update = true; + } + else // already initialized by application + { + region = radio->region_setting.country; + } + + ret = _mmradio_apply_region(radio, region, update); + + MMRADIO_CHECK_RETURN_IF_FAIL(ret, "update region info"); + } + + /* ready but nosound */ + if( _mmradio_mute(radio) != MM_ERROR_NONE) + goto error; + + MMRADIO_SET_STATE( radio, MM_RADIO_STATE_READY ); +#ifdef USE_GST_PIPELINE + ret = _mmradio_realize_pipeline(radio); + if ( ret ) { + debug_error("_mmradio_realize_pipeline is failed\n"); + return ret; + } +#endif + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; + +error: + if (radio->radio_fd >= 0) + { + close(radio->radio_fd); + radio->radio_fd = -1; + } + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_RADIO_INTERNAL; +} + +int +_mmradio_unrealize(mm_radio_t* radio) +{ + int ret = MM_ERROR_NONE; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE( radio ); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_UNREALIZE ); + + if( _mmradio_mute(radio) != MM_ERROR_NONE) + return MM_ERROR_RADIO_NOT_INITIALIZED; + + /* close radio device here !!!! */ + if (radio->radio_fd >= 0) + { + close(radio->radio_fd); + radio->radio_fd = -1; + } + + MMRADIO_SET_STATE( radio, MM_RADIO_STATE_NULL ); +#ifdef USE_GST_PIPELINE + ret= _mmradio_destroy_pipeline(radio); + if ( ret ) { + debug_error("_mmradio_destroy_pipeline is failed\n"); + return ret; + } +#endif + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; +} + +int +_mmradio_destroy(mm_radio_t* radio) +{ + int ret = 0; + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE( radio ); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_DESTROY ); + + ret = mmradio_asm_deregister(&radio->sm); + if ( ret ) + { + MMRADIO_LOG_ERROR("failed to deregister asm server\n"); + return MM_ERROR_RADIO_INTERNAL; + } + + _mmradio_unrealize( radio ); + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; +} + + +int +_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_LOG_DEBUG("Setting %d frequency\n", freq); + + radio->freq = freq; + + if (radio->radio_fd < 0) + { + MMRADIO_LOG_DEBUG("radio device is not opened yet. so, it will be applied\n", freq); + return MM_ERROR_NONE; + } + + /* check frequency range */ + if ( freq < radio->region_setting.band_min + || freq > radio->region_setting.band_max ) + { + MMRADIO_LOG_ERROR("out of frequency range\n", freq); + return MM_ERROR_INVALID_ARGUMENT; + } + + /* set it */ + (radio->vf).tuner = 0; + (radio->vf).frequency = RADIO_FREQ_FORMAT_SET(freq); + + if(ioctl(radio->radio_fd, VIDIOC_S_FREQUENCY, &(radio->vf))< 0) + { + return MM_ERROR_RADIO_NOT_INITIALIZED; + } + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; + +} + +int +_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 ); + + return_val_if_fail( pFreq, MM_ERROR_INVALID_ARGUMENT ); + + /* just return stored frequency if radio device is not ready */ + if ( radio->radio_fd < 0 ) + { + MMRADIO_LOG_DEBUG("freq : %d\n", radio->freq); + *pFreq = radio->freq; + return MM_ERROR_NONE; + } + + if (ioctl(radio->radio_fd, VIDIOC_G_FREQUENCY, &(radio->vf)) < 0) + { + MMRADIO_LOG_ERROR("failed to do VIDIOC_G_FREQUENCY\n"); + return MM_ERROR_RADIO_INTERNAL; + } + + freq = RADIO_FREQ_FORMAT_GET((radio->vf).frequency); + + /* update freq in handle */ + radio->freq = freq; + + *pFreq = radio->freq; + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; +} + +int +_mmradio_mute(mm_radio_t* radio) +{ + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE( radio ); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_MUTE ); + + if (radio->radio_fd < 0) + { + return MM_ERROR_RADIO_NOT_INITIALIZED; + } + + (radio->vctrl).id = V4L2_CID_AUDIO_MUTE; + (radio->vctrl).value = 1; //mute + + if (ioctl(radio->radio_fd, VIDIOC_S_CTRL, &(radio->vctrl)) < 0) + { + return MM_ERROR_RADIO_NOT_INITIALIZED; + } + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; + +} + +int +_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 ); + + (radio->vctrl).id = V4L2_CID_AUDIO_MUTE; + (radio->vctrl).value = 0; //unmute + + if (ioctl(radio->radio_fd, VIDIOC_S_CTRL, &(radio->vctrl)) < 0) + { + return MM_ERROR_RADIO_NOT_INITIALIZED; + } + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; +} + +/* -------------------------------------------------------------------------- + * Name : __mmradio_set_deemphasis + * Desc : apply de-emphasis value to device + * Param : + * [in] radio : radio handle + * Return : zero on success, or negative value with error code + *---------------------------------------------------------------------------*/ +int +__mmradio_set_deemphasis(mm_radio_t* radio) +{ + int value = 0; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE( radio ); + + /* get de-emphasis */ + switch (radio->region_setting.deemphasis) + { + case MM_RADIO_DEEMPHASIS_50_US: + value = 1;//V4L2_DEEMPHASIS_50_uS; + break; + + case MM_RADIO_DEEMPHASIS_75_US: + value = 2;//V4L2_DEEMPHASIS_75_uS; + break; + + default: + MMRADIO_LOG_ERROR("not availabe de-emphasis value\n"); + return MM_ERROR_COMMON_INVALID_ARGUMENT; + } + + /* set it to device */ + (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) + { + MMRADIO_LOG_ERROR("failed to set de-emphasis\n"); + return MM_ERROR_RADIO_INTERNAL; + } + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; +} + +/* -------------------------------------------------------------------------- + * Name : __mmradio_set_band_range + * Desc : apply max and min frequency to device + * Param : + * [in] radio : radio handle + * Return : zero on success, or negative value with error code + *---------------------------------------------------------------------------*/ +int +__mmradio_set_band_range(mm_radio_t* radio) +{ + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE( radio ); + + /* get min and max freq. */ + (radio->vt).rangelow = RADIO_FREQ_FORMAT_SET(radio->region_setting.band_min); + (radio->vt).rangehigh = RADIO_FREQ_FORMAT_SET(radio->region_setting.band_max); + + /* set it to device */ + if (ioctl(radio->radio_fd, VIDIOC_S_TUNER, &(radio->vt)) < 0 ) + { + MMRADIO_LOG_ERROR("failed to set band range\n"); + return MM_ERROR_RADIO_INTERNAL; + } + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; +} + +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; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE( radio ); + MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_START ); + + MMRADIO_LOG_DEBUG("now tune to frequency : %d\n", radio->freq); + + 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"); + return ret; + } + + /* set stored frequency */ + _mmradio_set_frequency( radio, radio->freq ); + + /* unmute */ + if( _mmradio_unmute(radio) != MM_ERROR_NONE) + return MM_ERROR_RADIO_NOT_INITIALIZED; + + MMRADIO_SET_STATE( radio, MM_RADIO_STATE_PLAYING ); +#ifdef USE_GST_PIPELINE + ret = _mmradio_start_pipeline( radio ); + if ( ret ) { + debug_error("_mmradio_start_pipeline is failed\n"); + return ret; + } +#endif + + MMRADIO_LOG_FLEAVE(); + + return ret; +} + +int +_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 ); + + if( _mmradio_mute(radio) != MM_ERROR_NONE) + return MM_ERROR_RADIO_NOT_INITIALIZED; + + MMRADIO_SET_STATE( radio, MM_RADIO_STATE_READY ); + + ret = mmradio_asm_set_state(&radio->sm, ASM_STATE_STOP, ASM_RESOURCE_NONE); + 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 ) { + debug_error("_mmradio_stop_pipeline is failed\n"); + return ret; + } +#endif + + MMRADIO_LOG_FLEAVE(); + + return ret; +} + +#ifdef USE_GST_PIPELINE +int +_mmradio_realize_pipeline(mm_radio_t* radio) +{ + int ret = MM_ERROR_NONE; + + gst_init (NULL, NULL); + radio->pGstreamer_s = g_new0 (mm_radio_gstreamer_s, 1); + + radio->pGstreamer_s->pipeline= gst_pipeline_new ("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 + +int +_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 ); + + int ret = 0; + + if( _mmradio_mute(radio) != MM_ERROR_NONE) + return MM_ERROR_RADIO_NOT_INITIALIZED; + + 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"); + return MM_ERROR_RADIO_INTERNAL; + } + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; +} + +int +_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 ); + + int scan_tr_id = 0; + + radio->stop_scan = 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"); + return MM_ERROR_RADIO_NOT_INITIALIZED; + } + + MMRADIO_SET_STATE( radio, MM_RADIO_STATE_SCANNING ); + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; +} + +int +_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 ); + + radio->stop_scan = true; + + if( radio->scan_thread > 0 ) + { + pthread_cancel(radio->scan_thread); + pthread_join(radio->scan_thread, NULL); + radio->scan_thread = 0; + } + + MMRADIO_SET_STATE( radio, MM_RADIO_STATE_READY ); + MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_STOP, NULL); + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; +} + +void +__mmradio_scan_thread(mm_radio_t* radio) +{ + int ret = 0; + int prev_freq = 0; + 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( radio ); + + if( _mmradio_mute(radio) != MM_ERROR_NONE) + goto FINISHED; + + 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 ); + + 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 ) + { + MMRADIO_LOG_ERROR("scanning timeout\n"); + continue; + } + else if ( errno == EINVAL ) + { + MMRADIO_LOG_ERROR("The tuner index is out of bounds or the value in the type field is wrong."); + break; + } + else + { + MMRADIO_LOG_ERROR("Error: %s, %d\n", strerror(errno), errno); + break; + } + } + + /* now we can get new frequency from radio device */ + + if ( radio->stop_scan ) break; + + ret = _mmradio_get_frequency(radio, &freq); + if ( ret ) + { + MMRADIO_LOG_ERROR("failed to get current frequency\n"); + } + else + { + if ( freq < prev_freq ) + { + MMRADIO_LOG_DEBUG("scanning wrapped around. stopping scan\n"); + break; + } + + if ( freq == prev_freq) + continue; + + 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; + + MMRADIO_SET_STATE( radio, MM_RADIO_STATE_READY ); + + if ( ! radio->stop_scan ) + { + MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_FINISH, NULL); + } + + MMRADIO_LOG_FLEAVE(); + + pthread_exit(NULL); +} + +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 false; + + MMRADIO_LOG_FLEAVE(); + + return true; +} + +void +__mmradio_seek_thread(mm_radio_t* radio) +{ + int ret = 0; + int freq = 0; + bool seek_stop = false; + MMMessageParamType param = {0,}; + struct v4l2_hw_freq_seek vs = {0,}; + + vs.tuner = TUNER_INDEX; + vs.type = V4L2_TUNER_RADIO; + vs.wrap_around = DEFAULT_WRAP_AROUND; + + MMRADIO_LOG_FENTER(); + + MMRADIO_CHECK_INSTANCE( radio ); + + /* check direction */ + switch( radio->seek_direction ) + { + case MM_RADIO_SEEK_UP: + vs.seek_upward = 1; + break; + default: + vs.seek_upward = 0; + break; + } + + MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_START, NULL); + + MMRADIO_LOG_DEBUG("seeking....\n"); + + while ( ! seek_stop ) + { + ret = ioctl( radio->radio_fd, VIDIOC_S_HW_FREQ_SEEK, &vs ); + + if( ret == -1 ) + { + if ( errno == EAGAIN ) + { + /* FIXIT : we need retrying code here */ + MMRADIO_LOG_ERROR("scanning timeout\n"); + goto SEEK_FAILED; + } + else if ( errno == EINVAL ) + { + MMRADIO_LOG_ERROR("The tuner index is out of bounds or the value in the type field is wrong."); + goto SEEK_FAILED; + } + else + { + MMRADIO_LOG_ERROR("Error: %s, %d\n", strerror(errno), errno); + goto SEEK_FAILED; + } + } + + /* now we can get new frequency from radio device */ + ret = _mmradio_get_frequency(radio, &freq); + if ( ret ) + { + MMRADIO_LOG_ERROR("failed to get current frequency\n"); + goto SEEK_FAILED; + } + + MMRADIO_LOG_DEBUG("found frequency = %d\n", 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 one(%d). So, trying next one. \n", freq); + continue; + } + + 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; + } + } + + /* now turn on radio + * In the case of limit freq, tuner should be unmuted. + * Otherwise, sound can't output even though application set new frequency. + */ + ret = _mmradio_unmute(radio); + if ( ret ) + { + MMRADIO_LOG_ERROR("failed to tune to new frequency\n"); + goto SEEK_FAILED; + } + + 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); + seek_stop = true; + } + + radio->seek_thread = 0; + + MMRADIO_LOG_FLEAVE(); + + pthread_exit(NULL); + return; + +SEEK_FAILED: + /* freq -1 means it's failed to seek */ + param.radio_scan.frequency = -1; + MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, ¶m); + pthread_exit(NULL); +} + +static bool +__mmradio_post_message(mm_radio_t* radio, enum MMMessageType msgtype, MMMessageParamType* param) +{ + MMRADIO_CHECK_INSTANCE( radio ); + + MMRADIO_LOG_FENTER(); + + if ( !radio->msg_cb ) + { + debug_warning("failed to post a message\n"); + return false; + } + + MMRADIO_LOG_DEBUG("address of msg_cb : %d\n", radio->msg_cb); + + radio->msg_cb(msgtype, param, radio->msg_cb_param); + + MMRADIO_LOG_FLEAVE(); + + return 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_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; + + + INVALID_STATE: + debug_warning("invalid state. current : %d command : %d\n", + radio_state, command); + MMRADIO_LOG_FLEAVE(); + return MM_ERROR_RADIO_INVALID_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; + + } + +static bool +__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 ); + + if ( ! radio ) + { + debug_warning("calling set_state with invalid radio handle\n"); + return false; + } + + if ( radio->current_state == new_state && radio->pending_state == 0 ) + { + debug_warning("we are in same state\n"); + return 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, 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; + } + + MMRADIO_LOG_FLEAVE(); + + return 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; +} + +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: + 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_SKIP_POSTMSG; + result = _mmradio_stop(radio); + if( result ) + { + MMRADIO_LOG_ERROR("failed to stop radio\n"); + } + + radio->sm.by_asm_cb = MMRADIO_ASM_CB_POSTMSG; + result = _mmradio_unrealize(radio); + if ( result ) + { + MMRADIO_LOG_ERROR("failed to unrealize radio\n"); + } + } + break; + } + cb_res = ASM_CB_RES_STOP; + } + break; + + case ASM_COMMAND_PLAY: + 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); + + cb_res = ASM_CB_RES_IGNORE; + radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE; + } + break; + + default: + break; + } + + MMRADIO_LOG_FLEAVE(); + + return cb_res; +} + +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; +} diff --git a/test/Makefile.am b/test/Makefile.am new file mode 100644 index 0000000..3b6bc99 --- /dev/null +++ b/test/Makefile.am @@ -0,0 +1,14 @@ +bin_PROGRAMS = mm_radio_testsuite + +mm_radio_testsuite_SOURCES = mm_radio_testsuite.c \ + mm_radio_rt_api_test.c + +mm_radio_testsuite_CFLAGS = -I$(srcdir)/../src/include \ + $(MMCOMMON_CFLAGS) \ + $(MMTA_CFLAGS) + +mm_radio_testsuite_DEPENDENCIES = $(top_builddir)/src/libmmfradio.la + +mm_radio_testsuite_LDADD = $(top_builddir)/src/libmmfradio.la \ + $(MMCOMMON_LIBS) \ + $(MMTA_LIBS) diff --git a/test/mm_radio_rt_api_test.c b/test/mm_radio_rt_api_test.c new file mode 100644 index 0000000..2b611ff --- /dev/null +++ b/test/mm_radio_rt_api_test.c @@ -0,0 +1,262 @@ +/* + * libmm-radio + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YoungHwan An <younghwan_.an@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include <stdio.h> + +#include "mm_radio.h" +#include "mm_radio_rt_api_test.h" + +#define MENU_ITEM_MAX 18 + +static int __menu(void); +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 ) +{ + 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: + { + 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; + + 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; + + 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: + { + 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; + + default: + break; + } +} + +int mm_radio_rt_api_test(void) +{ + while(1) + { + char key = 0; + int choosen = 0; + + choosen = __menu(); + + if ( choosen == -1) + continue; + + if ( choosen == 0 ) + break; + + __call_api( choosen ); + } + + printf("radio test client finished\n"); + + return 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(ex.107700)\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("[17] mm_radio_get_region_type\n"); + printf("[18] mm_radio_get_region_frequency_range\n"); + printf("[0] quit\n"); + printf("---------------------------------------------------------\n"); + printf("choose one : "); + + if ( scanf("%d", &menu_item) == 0) + return -1; + + if ( menu_item > MENU_ITEM_MAX ) + menu_item = -1; + + return menu_item; +} + + +int __msg_rt_callback(int message, void *pParam, void *user_param) +{ + 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: + 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; +} diff --git a/test/mm_radio_rt_api_test.h b/test/mm_radio_rt_api_test.h new file mode 100644 index 0000000..66b6067 --- /dev/null +++ b/test/mm_radio_rt_api_test.h @@ -0,0 +1,29 @@ +/* + * libmm-radio + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YoungHwan An <younghwan_.an@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef MM_RADIO_RT_API_TEST_H_ +#define MM_RADIO_RT_API_TEST_H_ + +#include "mm_radio_test_type.h" + +int mm_radio_rt_api_test(void); + +#endif /* MM_RADIO_RT_API_TEST_H_ */ diff --git a/test/mm_radio_test_type.h b/test/mm_radio_test_type.h new file mode 100644 index 0000000..ead49e9 --- /dev/null +++ b/test/mm_radio_test_type.h @@ -0,0 +1,49 @@ +/* + * libmm-radio + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YoungHwan An <younghwan_.an@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef MM_RADIO_TEST_TYPE_H_ +#define MM_RADIO_TEST_TYPE_H_ + +#include <stdio.h> +#include <assert.h> + +typedef int (*test_function) (void); + +typedef struct __test_item +{ + char menu_string[80]; + 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__); \ + } + +#endif /* MM_RADIO_TEST_TYPE_H_ */ diff --git a/test/mm_radio_testsuite.c b/test/mm_radio_testsuite.c new file mode 100644 index 0000000..104ba7f --- /dev/null +++ b/test/mm_radio_testsuite.c @@ -0,0 +1,330 @@ +/* + * libmm-radio + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YoungHwan An <younghwan_.an@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/* testsuite for mm-radio library */ +#include <stdlib.h> +#include <stdio.h> +#include <mm_ta.h> + + +#include "mm_radio.h" +#include "mm_radio_test_type.h" +#include "mm_radio_rt_api_test.h" + +#define DEFAULT_TEST_FREQ 107700 + +/* test items...*/ +int __test_radio_init(void); +int __test_radio_listen_gorealra(void); +int __test_repeat_init_release(void); +int __test_repeat_start_stop(void); +int __test_repeat_seek(void); +int __test_repeat_whole(void); +int __test_manual_api_calling(void); +int __test_radio_hw_debug(void); + +static int __msg_callback(int message, void *param, void *user_param); + +/* functions*/ +static void __print_menu(void); +static void __run_test(int key); + +/* list of tests*/ +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 + 0 : to be filled with return value of test function + */ + { + "init test", + "check radio init function", + __test_radio_init, + 0 + }, + + { + "listening gorealra", + "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_start_stop", + "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_whole", + "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 + }, + + /* add tests here*/ + + /* NOTE : do not remove this last item */ + {"end", "", NULL, 0}, +}; + +int g_num_of_tests = 0; + +int main(int argc, char **argv) +{ + MMTA_INIT(); + int key = 0; + + do { + __print_menu(); + + do { + key = getchar(); + + if ( key >= '0' && key <= '9') + { + __run_test( key - '0' ); + } + }while ( key == '\n' ); + }while(key != 'q' && key == 'Q'); + + printf("radio test client finished\n"); + + return 0; +} + +void __print_menu(void) +{ + int i = 0; + + 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 ); + } + printf("[q] quit\n"); + + g_num_of_tests = i; + + printf("Choose one : "); +} + +void __run_test(int key) +{ + int ret = 0; + + /* check index */ + printf("#tests : %d key : %d\n", g_num_of_tests, key); + 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 ); + + /* 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); + } +} + +static int __msg_callback(int message, void *pParam, void *user_param) +{ + 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: + 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; + default: + printf("ERROR : unknown message received!\n"); + break; + } + + return true; +} + +/* test items...*/ +int __test_radio_init(void) +{ + printf("%s\n", __FUNCTION__); + + 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); ) + return ret; +} + +int __test_radio_listen_gorealra(void) +{ + printf("%s\n", __FUNCTION__); + + 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); ) + + return ret; +} + +int __test_repeat_init_release(void) +{ + printf("%s\n", __FUNCTION__); + + int ret = MM_ERROR_NONE; + 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); ) + + cnt++; + + printf("%s : repeat count : %d\n", __FUNCTION__, cnt); + } + + return 0; +} + +int __test_repeat_start_stop(void) +{ + printf("%s\n", __FUNCTION__); + int ret = MM_ERROR_NONE; + 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 ); ) + + while(1) + { + RADIO_TEST__( mm_radio_start(radio); ) + RADIO_TEST__( mm_radio_stop(radio); ) + + cnt++; + + printf("%s : repeat count : %d\n", __FUNCTION__, cnt); + } + + return 0; +} + +int __test_repeat_seek(void) +{ + printf("__test_repeat_seek\n"); + return 0; +} + +int __test_repeat_whole(void) +{ + printf("__test_repeat_whole\n"); + return 0; +} + +int __test_manual_api_calling(void) +{ + + mm_radio_rt_api_test(); + + return 0; +} + |