4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
22 /*===========================================================================================
26 ========================================================================================== */
33 #include <sys/ioctl.h>
39 #include <mm_message.h>
41 #include <mm_sound_device.h>
43 #include "mm_radio_priv.h"
45 /*===========================================================================================
46 LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE
47 ========================================================================================== */
48 /*---------------------------------------------------------------------------
49 GLOBAL CONSTANT DEFINITIONS:
50 ---------------------------------------------------------------------------*/
52 /*---------------------------------------------------------------------------
53 IMPORTED VARIABLE DECLARATIONS:
54 ---------------------------------------------------------------------------*/
56 /*---------------------------------------------------------------------------
57 IMPORTED FUNCTION DECLARATIONS:
58 ---------------------------------------------------------------------------*/
60 /*---------------------------------------------------------------------------
62 ---------------------------------------------------------------------------*/
63 #define DEFAULT_DEVICE "/dev/radio0"
66 #define DEFAULT_FREQ 107700
69 #define RADIO_FREQ_FORMAT_SET(x_freq) ((x_freq) * FREQ_FRAC)
70 #define RADIO_FREQ_FORMAT_GET(x_freq) ((x_freq) / FREQ_FRAC)
71 #define DEFAULT_WRAP_AROUND 1 //If non-zero, wrap around when at the end of the frequency range, else stop seeking
73 #define RADIO_DEFAULT_REGION MM_RADIO_REGION_GROUP_USA
74 #define READ_MAX_BUFFER_SIZE 1024
75 /*---------------------------------------------------------------------------
76 LOCAL CONSTANT DEFINITIONS:
77 ---------------------------------------------------------------------------*/
79 /*---------------------------------------------------------------------------
80 LOCAL DATA TYPE DEFINITIONS:
81 ---------------------------------------------------------------------------*/
83 /*---------------------------------------------------------------------------
84 GLOBAL VARIABLE DEFINITIONS:
85 ---------------------------------------------------------------------------*/
88 /*---------------------------------------------------------------------------
89 LOCAL VARIABLE DEFINITIONS:
90 ---------------------------------------------------------------------------*/
91 /* radio region configuration table */
92 static const MMRadioRegion_t region_table[] =
94 { /* Notrh America, South America, South Korea, Taiwan, Australia */
95 MM_RADIO_REGION_GROUP_USA, // region type
96 MM_RADIO_DEEMPHASIS_75_US, // de-emphasis
97 MM_RADIO_FREQ_MIN_87500_KHZ, // min freq.
98 MM_RADIO_FREQ_MAX_108000_KHZ, // max freq.
101 { /* China, Europe, Africa, Middle East, Hong Kong, India, Indonesia, Russia, Singapore */
102 MM_RADIO_REGION_GROUP_EUROPE,
103 MM_RADIO_DEEMPHASIS_50_US,
104 MM_RADIO_FREQ_MIN_87500_KHZ,
105 MM_RADIO_FREQ_MAX_108000_KHZ,
109 MM_RADIO_REGION_GROUP_JAPAN,
110 MM_RADIO_DEEMPHASIS_50_US,
111 MM_RADIO_FREQ_MIN_76100_KHZ,
112 MM_RADIO_FREQ_MAX_89900_KHZ,
116 /*---------------------------------------------------------------------------
117 LOCAL FUNCTION PROTOTYPES:
118 ---------------------------------------------------------------------------*/
119 static bool __mmradio_post_message(mm_radio_t* radio, enum MMMessageType msgtype, MMMessageParamType* param);
120 static int __mmradio_check_state(mm_radio_t* radio, MMRadioCommand command);
121 static int __mmradio_get_state(mm_radio_t* radio);
122 static bool __mmradio_set_state(mm_radio_t* radio, int new_state);
123 static void __mmradio_seek_thread(mm_radio_t* radio);
124 static void __mmradio_scan_thread(mm_radio_t* radio);
125 static bool __is_tunable_frequency(mm_radio_t* radio, int freq);
126 static int __mmradio_set_deemphasis(mm_radio_t* radio);
127 static int __mmradio_set_band_range(mm_radio_t* radio);
128 static void __mmradio_device_connected_cb(MMSoundDevice_t device, bool is_connected, void *user_data);
130 /*===========================================================================
132 ========================================================================== */
133 /* --------------------------------------------------------------------------
134 * Name : _mmradio_apply_region()
135 * Desc : update radio region information and set values to device
137 * [in] radio : radio handle
138 * [in] region : region type
139 * [in] update : update region values or not
140 * Return : zero on success, or negative value with error code
141 *---------------------------------------------------------------------------*/
143 _mmradio_apply_region(mm_radio_t* radio, MMRadioRegionType region, bool update)
145 int ret = MM_ERROR_NONE;
149 MMRADIO_LOG_FENTER();
151 MMRADIO_CHECK_INSTANCE( radio );
152 MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_SET_REGION );
154 /* if needed, radio region must be updated.
155 * Otherwise, just applying settings to device without it.
159 count = ARRAY_SIZE(region_table);
161 //TODO: if auto is supported...get the region info. here
163 /* update radio region settings */
164 for ( index = 0; index < count; index++ )
166 /* find the region from pre-defined table*/
167 if (region_table[index].country == region)
169 radio->region_setting.country = region_table[index].country;
170 radio->region_setting.deemphasis = region_table[index].deemphasis;
171 radio->region_setting.band_min = region_table[index].band_min;
172 radio->region_setting.band_max = region_table[index].band_max;
173 radio->region_setting.channel_spacing = region_table[index].channel_spacing;
178 /* chech device is opened or not. if it's not ready, skip to apply region to device now*/
179 if (radio->radio_fd < 0)
181 MMRADIO_LOG_DEBUG("not opened device. just updating region info. \n");
182 return MM_ERROR_NONE;
185 MMRADIO_LOG_DEBUG("setting region - country: %d, de-emphasis: %d, band range: %d ~ %d KHz\n",
186 radio->region_setting.country, radio->region_setting.deemphasis, radio->region_setting.band_min, radio->region_setting.band_max);
188 /* set de-emphsasis to device */
189 ret = __mmradio_set_deemphasis(radio);
191 MMRADIO_CHECK_RETURN_IF_FAIL(ret, "set de-emphasis");
193 /* set band range to device */
194 ret = __mmradio_set_band_range(radio);
196 MMRADIO_CHECK_RETURN_IF_FAIL(ret, "set band range");
198 MMRADIO_LOG_FLEAVE();
204 _mmradio_create_radio(mm_radio_t* radio)
208 MMRADIO_LOG_FENTER();
210 MMRADIO_CHECK_INSTANCE( radio );
211 MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_CREATE );
213 /* set default value */
214 radio->radio_fd = -1;
215 radio->freq = DEFAULT_FREQ;
216 memset(&radio->region_setting, 0, sizeof(MMRadioRegion_t));
219 /* create command lock */
220 ret = pthread_mutex_init( &radio->cmd_lock, NULL );
223 MMRADIO_LOG_ERROR("mutex creation failed\n");
224 return MM_ERROR_RADIO_INTERNAL;
227 MMRADIO_SET_STATE( radio, MM_RADIO_STATE_NULL );
229 /* add device conneted callback */
230 ret = mm_sound_add_device_connected_callback(MM_SOUND_DEVICE_STATE_ACTIVATED_FLAG,
231 (mm_sound_device_connected_cb)__mmradio_device_connected_cb,
232 (void *)radio, &radio->subs_id);
235 MMRADIO_LOG_ERROR("mm_sound_add_device_connected_callback is failed\n");
236 return MM_ERROR_RADIO_INTERNAL;
239 /* register to audio focus */
240 ret = mmradio_audio_focus_register(&radio->sm, _mmradio_sound_focus_cb, (void *)radio);
243 /* NOTE : we are dealing it as an error since we cannot expect it's behavior */
244 MMRADIO_LOG_ERROR("failed to register audio focus\n");
245 return MM_ERROR_RADIO_INTERNAL;
248 MMRADIO_LOG_FLEAVE();
250 return MM_ERROR_NONE;
254 _mmradio_realize(mm_radio_t* radio)
256 int ret = MM_ERROR_NONE;
257 char str_error[READ_MAX_BUFFER_SIZE];
259 MMRADIO_LOG_FENTER();
261 MMRADIO_CHECK_INSTANCE( radio );
262 MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_REALIZE );
264 /* open radio device */
265 if(radio->radio_fd == -1)
267 MMRadioRegionType region = MM_RADIO_REGION_GROUP_NONE;
271 radio->radio_fd = open(DEFAULT_DEVICE, O_RDONLY);
272 if (radio->radio_fd < 0)
274 MMRADIO_LOG_ERROR("failed to open radio device[%s] because of %s(%d)\n",
275 DEFAULT_DEVICE, strerror_r(errno, str_error, sizeof(str_error)), errno);
281 return MM_ERROR_RADIO_DEVICE_NOT_FOUND;
283 return MM_ERROR_RADIO_PERMISSION_DENIED;
285 return MM_ERROR_RADIO_DEVICE_NOT_OPENED;
288 MMRADIO_LOG_DEBUG("radio device fd : %d\n", radio->radio_fd);
290 /* query radio device capabilities. */
291 if (ioctl(radio->radio_fd, VIDIOC_QUERYCAP, &(radio->vc)) < 0)
293 MMRADIO_LOG_ERROR("VIDIOC_QUERYCAP failed!\n");
297 if ( ! ( radio->vc.capabilities & V4L2_CAP_TUNER) )
299 MMRADIO_LOG_ERROR("this system can't support fm-radio!\n");
303 /* set tuner audio mode */
304 ioctl(radio->radio_fd, VIDIOC_G_TUNER, &(radio->vt));
306 if ( ! ( (radio->vt).capability & V4L2_TUNER_CAP_STEREO) )
308 MMRADIO_LOG_ERROR("this system can support mono!\n");
309 (radio->vt).audmode = V4L2_TUNER_MODE_MONO;
313 (radio->vt).audmode = V4L2_TUNER_MODE_STEREO;
316 /* set tuner index. Must be 0. */
317 (radio->vt).index = TUNER_INDEX;
318 ioctl(radio->radio_fd, VIDIOC_S_TUNER, &(radio->vt));
320 /* check region country type if it's updated or not */
321 if ( radio->region_setting.country == MM_RADIO_REGION_GROUP_NONE)
323 /* not initialized yet. set it with default region */
324 region = RADIO_DEFAULT_REGION;
327 else // already initialized by application
329 region = radio->region_setting.country;
332 ret = _mmradio_apply_region(radio, region, update);
334 MMRADIO_CHECK_RETURN_IF_FAIL(ret, "update region info");
337 /* ready but nosound */
338 if( _mmradio_mute(radio) != MM_ERROR_NONE)
341 MMRADIO_SET_STATE( radio, MM_RADIO_STATE_READY );
342 #ifdef USE_GST_PIPELINE
343 ret = _mmradio_realize_pipeline(radio);
345 debug_error("_mmradio_realize_pipeline is failed\n");
349 MMRADIO_LOG_FLEAVE();
351 return MM_ERROR_NONE;
354 if (radio->radio_fd >= 0)
356 close(radio->radio_fd);
357 radio->radio_fd = -1;
360 MMRADIO_LOG_FLEAVE();
362 return MM_ERROR_RADIO_INTERNAL;
366 _mmradio_unrealize(mm_radio_t* radio)
368 int ret = MM_ERROR_NONE;
370 MMRADIO_LOG_FENTER();
372 MMRADIO_CHECK_INSTANCE( radio );
373 MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_UNREALIZE );
375 if( _mmradio_mute(radio) != MM_ERROR_NONE)
376 return MM_ERROR_RADIO_NOT_INITIALIZED;
378 /* close radio device here !!!! */
379 if (radio->radio_fd >= 0)
381 close(radio->radio_fd);
382 radio->radio_fd = -1;
385 MMRADIO_SET_STATE( radio, MM_RADIO_STATE_NULL );
387 ret = mmradio_unset_audio_focus(&radio->sm, (void *)radio);
389 MMRADIO_LOG_ERROR("failed to unset audio focus\n");
392 #ifdef USE_GST_PIPELINE
393 ret= _mmradio_destroy_pipeline(radio);
395 debug_error("_mmradio_destroy_pipeline is failed\n");
400 MMRADIO_LOG_FLEAVE();
402 return MM_ERROR_NONE;
406 _mmradio_destroy(mm_radio_t* radio)
409 MMRADIO_LOG_FENTER();
411 MMRADIO_CHECK_INSTANCE( radio );
412 MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_DESTROY );
414 ret = mmradio_audio_focus_deregister(&radio->sm);
417 MMRADIO_LOG_ERROR("failed to deregister audio focus\n");
418 return MM_ERROR_RADIO_INTERNAL;
421 ret = mm_sound_remove_device_connected_callback(radio->subs_id);
424 MMRADIO_LOG_ERROR("mm_sound_remove_device_connected_callback error %d\n", ret);
425 return MM_ERROR_RADIO_INTERNAL;
427 _mmradio_unrealize( radio );
429 MMRADIO_LOG_FLEAVE();
431 return MM_ERROR_NONE;
436 _mmradio_set_frequency(mm_radio_t* radio, int freq) // unit should be KHz
438 MMRADIO_LOG_FENTER();
440 MMRADIO_CHECK_INSTANCE( radio );
441 MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_SET_FREQ );
443 MMRADIO_LOG_DEBUG("Setting %d frequency\n", freq);
447 if (radio->radio_fd < 0)
449 MMRADIO_LOG_DEBUG("radio device is not opened yet\n");
450 return MM_ERROR_NONE;
453 /* check frequency range */
454 if ( freq < radio->region_setting.band_min
455 || freq > radio->region_setting.band_max )
457 MMRADIO_LOG_ERROR("out of frequency range\n", freq);
458 return MM_ERROR_INVALID_ARGUMENT;
462 (radio->vf).tuner = 0;
463 (radio->vf).frequency = RADIO_FREQ_FORMAT_SET(freq);
465 if(ioctl(radio->radio_fd, VIDIOC_S_FREQUENCY, &(radio->vf))< 0)
467 return MM_ERROR_RADIO_NOT_INITIALIZED;
470 MMRADIO_LOG_FLEAVE();
472 return MM_ERROR_NONE;
477 _mmradio_get_frequency(mm_radio_t* radio, int* pFreq)
480 MMRADIO_LOG_FENTER();
482 MMRADIO_CHECK_INSTANCE( radio );
483 MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_GET_FREQ );
485 return_val_if_fail( pFreq, MM_ERROR_INVALID_ARGUMENT );
487 /* just return stored frequency if radio device is not ready */
488 if ( radio->radio_fd < 0 )
490 MMRADIO_LOG_DEBUG("freq : %d\n", radio->freq);
491 *pFreq = radio->freq;
492 return MM_ERROR_NONE;
495 if (ioctl(radio->radio_fd, VIDIOC_G_FREQUENCY, &(radio->vf)) < 0)
497 MMRADIO_LOG_ERROR("failed to do VIDIOC_G_FREQUENCY\n");
498 return MM_ERROR_RADIO_INTERNAL;
501 freq = RADIO_FREQ_FORMAT_GET((radio->vf).frequency);
503 /* update freq in handle */
506 *pFreq = radio->freq;
508 MMRADIO_LOG_FLEAVE();
510 return MM_ERROR_NONE;
514 _mmradio_mute(mm_radio_t* radio)
516 MMRADIO_LOG_FENTER();
518 MMRADIO_CHECK_INSTANCE( radio );
519 MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_MUTE );
521 if (radio->radio_fd < 0)
523 return MM_ERROR_RADIO_NOT_INITIALIZED;
526 (radio->vctrl).id = V4L2_CID_AUDIO_MUTE;
527 (radio->vctrl).value = 1; //mute
529 if (ioctl(radio->radio_fd, VIDIOC_S_CTRL, &(radio->vctrl)) < 0)
531 return MM_ERROR_RADIO_NOT_INITIALIZED;
534 MMRADIO_LOG_FLEAVE();
536 return MM_ERROR_NONE;
541 _mmradio_unmute(mm_radio_t* radio)
543 MMRADIO_LOG_FENTER();
545 MMRADIO_CHECK_INSTANCE( radio );
546 MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_UNMUTE );
547 MMRADIO_CHECK_DEVICE_STATE( radio );
549 (radio->vctrl).id = V4L2_CID_AUDIO_MUTE;
550 (radio->vctrl).value = 0; //unmute
552 if (ioctl(radio->radio_fd, VIDIOC_S_CTRL, &(radio->vctrl)) < 0)
554 return MM_ERROR_RADIO_NOT_INITIALIZED;
557 MMRADIO_LOG_FLEAVE();
559 return MM_ERROR_NONE;
562 /* --------------------------------------------------------------------------
563 * Name : __mmradio_set_deemphasis
564 * Desc : apply de-emphasis value to device
566 * [in] radio : radio handle
567 * Return : zero on success, or negative value with error code
568 *---------------------------------------------------------------------------*/
570 __mmradio_set_deemphasis(mm_radio_t* radio)
574 MMRADIO_LOG_FENTER();
576 MMRADIO_CHECK_INSTANCE( radio );
578 /* get de-emphasis */
579 switch (radio->region_setting.deemphasis)
581 case MM_RADIO_DEEMPHASIS_50_US:
582 value = 1;//V4L2_DEEMPHASIS_50_uS;
585 case MM_RADIO_DEEMPHASIS_75_US:
586 value = 2;//V4L2_DEEMPHASIS_75_uS;
590 MMRADIO_LOG_ERROR("not availabe de-emphasis value\n");
591 return MM_ERROR_COMMON_INVALID_ARGUMENT;
594 /* set it to device */
595 (radio->vctrl).id = (0x009d0000 | 0x900) +1;//V4L2_CID_TUNE_DEEMPHASIS;
596 (radio->vctrl).value = value;
598 if (ioctl(radio->radio_fd, VIDIOC_S_CTRL, &(radio->vctrl)) < 0)
600 MMRADIO_LOG_ERROR("failed to set de-emphasis\n");
601 return MM_ERROR_RADIO_INTERNAL;
604 MMRADIO_LOG_FLEAVE();
606 return MM_ERROR_NONE;
609 /* --------------------------------------------------------------------------
610 * Name : __mmradio_set_band_range
611 * Desc : apply max and min frequency to device
613 * [in] radio : radio handle
614 * Return : zero on success, or negative value with error code
615 *---------------------------------------------------------------------------*/
617 __mmradio_set_band_range(mm_radio_t* radio)
619 MMRADIO_LOG_FENTER();
621 MMRADIO_CHECK_INSTANCE( radio );
623 /* get min and max freq. */
624 (radio->vt).rangelow = RADIO_FREQ_FORMAT_SET(radio->region_setting.band_min);
625 (radio->vt).rangehigh = RADIO_FREQ_FORMAT_SET(radio->region_setting.band_max);
627 /* set it to device */
628 if (ioctl(radio->radio_fd, VIDIOC_S_TUNER, &(radio->vt)) < 0 )
630 MMRADIO_LOG_ERROR("failed to set band range\n");
631 return MM_ERROR_RADIO_INTERNAL;
634 MMRADIO_LOG_FLEAVE();
636 return MM_ERROR_NONE;
640 _mmradio_set_message_callback(mm_radio_t* radio, MMMessageCallback callback, void *user_param)
642 MMRADIO_LOG_FENTER();
644 MMRADIO_CHECK_INSTANCE( radio );
646 radio->msg_cb = callback;
647 radio->msg_cb_param = user_param;
649 MMRADIO_LOG_DEBUG("msg_cb : 0x%x msg_cb_param : 0x%x\n", (unsigned int)callback, (unsigned int)user_param);
651 MMRADIO_LOG_FLEAVE();
653 return MM_ERROR_NONE;
657 _mmradio_get_state(mm_radio_t* radio, int* pState)
661 MMRADIO_LOG_FENTER();
663 MMRADIO_CHECK_INSTANCE( radio );
664 return_val_if_fail( pState, MM_ERROR_INVALID_ARGUMENT );
666 state = __mmradio_get_state( radio );
670 MMRADIO_LOG_FLEAVE();
672 return MM_ERROR_NONE;
676 _mmradio_start(mm_radio_t* radio)
678 int ret = MM_ERROR_NONE;
680 MMRADIO_LOG_FENTER();
682 MMRADIO_CHECK_INSTANCE( radio );
683 MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_START );
685 MMRADIO_LOG_DEBUG("now tune to frequency : %d\n", radio->freq);
687 ret = mmradio_set_audio_focus(&radio->sm, _mmradio_sound_focus_watch_cb, (void *)radio);
690 MMRADIO_LOG_ERROR("failed to set audio focus\n");
694 /* set stored frequency */
695 _mmradio_set_frequency( radio, radio->freq );
698 if( _mmradio_unmute(radio) != MM_ERROR_NONE)
699 return MM_ERROR_RADIO_NOT_INITIALIZED;
701 MMRADIO_SET_STATE( radio, MM_RADIO_STATE_PLAYING );
702 #ifdef USE_GST_PIPELINE
703 ret = _mmradio_start_pipeline( radio );
705 debug_error("_mmradio_start_pipeline is failed\n");
710 MMRADIO_LOG_FLEAVE();
716 _mmradio_stop(mm_radio_t* radio)
718 int ret = MM_ERROR_NONE;
720 MMRADIO_LOG_FENTER();
722 MMRADIO_CHECK_INSTANCE( radio );
723 MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_STOP );
725 if( _mmradio_mute(radio) != MM_ERROR_NONE)
726 return MM_ERROR_RADIO_NOT_INITIALIZED;
728 MMRADIO_SET_STATE( radio, MM_RADIO_STATE_READY );
730 #ifdef USE_GST_PIPELINE
731 ret= _mmradio_stop_pipeline( radio );
733 debug_error("_mmradio_stop_pipeline is failed\n");
738 MMRADIO_LOG_FLEAVE();
743 #ifdef USE_GST_PIPELINE
745 _mmradio_realize_pipeline(mm_radio_t* radio)
747 int ret = MM_ERROR_NONE;
749 gst_init (NULL, NULL);
750 radio->pGstreamer_s = g_new0 (mm_radio_gstreamer_s, 1);
752 radio->pGstreamer_s->pipeline= gst_pipeline_new ("fmradio");
754 radio->pGstreamer_s->audiosrc= gst_element_factory_make("pulsesrc","fm audio src");
755 radio->pGstreamer_s->queue2= gst_element_factory_make("queue2","queue2");
756 radio->pGstreamer_s->audiosink= gst_element_factory_make("pulsesink","audio sink");
758 // g_object_set(radio->pGstreamer_s->audiosrc, "latency", 2, NULL);
759 g_object_set(radio->pGstreamer_s->audiosink, "sync", false, NULL);
761 if (!radio->pGstreamer_s->pipeline || !radio->pGstreamer_s->audiosrc || !radio->pGstreamer_s->queue2 || !radio->pGstreamer_s->audiosink) {
762 debug_error("[%s][%05d] One element could not be created. Exiting.\n", __func__, __LINE__);
763 return MM_ERROR_RADIO_NOT_INITIALIZED;
766 gst_bin_add_many(GST_BIN(radio->pGstreamer_s->pipeline),
767 radio->pGstreamer_s->audiosrc,
768 radio->pGstreamer_s->queue2,
769 radio->pGstreamer_s->audiosink,
771 if(!gst_element_link_many(
772 radio->pGstreamer_s->audiosrc,
773 radio->pGstreamer_s->queue2,
774 radio->pGstreamer_s->audiosink,
776 debug_error("[%s][%05d] Fail to link b/w appsrc and ffmpeg in rotate\n", __func__, __LINE__);
777 return MM_ERROR_RADIO_NOT_INITIALIZED;
783 _mmradio_start_pipeline(mm_radio_t* radio)
785 int ret = MM_ERROR_NONE;
786 GstStateChangeReturn ret_state;
789 if(gst_element_set_state (radio->pGstreamer_s->pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
790 debug_error("Fail to change pipeline state");
791 gst_object_unref (radio->pGstreamer_s->pipeline);
792 g_free (radio->pGstreamer_s);
793 return MM_ERROR_RADIO_INVALID_STATE;
796 ret_state = gst_element_get_state (radio->pGstreamer_s->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
797 if (ret_state == GST_STATE_CHANGE_FAILURE) {
798 debug_error("GST_STATE_CHANGE_FAILURE");
799 gst_object_unref (radio->pGstreamer_s->pipeline);
800 g_free (radio->pGstreamer_s);
801 return MM_ERROR_RADIO_INVALID_STATE;
803 debug_log("[%s][%05d] GST_STATE_NULL ret_state = %d (GST_STATE_CHANGE_SUCCESS)\n", __func__, __LINE__, ret_state);
809 _mmradio_stop_pipeline(mm_radio_t* radio)
811 int ret = MM_ERROR_NONE;
812 GstStateChangeReturn ret_state;
815 if(gst_element_set_state (radio->pGstreamer_s->pipeline, GST_STATE_READY) == GST_STATE_CHANGE_FAILURE) {
816 debug_error("Fail to change pipeline state");
817 gst_object_unref (radio->pGstreamer_s->pipeline);
818 g_free (radio->pGstreamer_s);
819 return MM_ERROR_RADIO_INVALID_STATE;
822 ret_state = gst_element_get_state (radio->pGstreamer_s->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
823 if (ret_state == GST_STATE_CHANGE_FAILURE) {
824 debug_error("GST_STATE_CHANGE_FAILURE");
825 gst_object_unref (radio->pGstreamer_s->pipeline);
826 g_free (radio->pGstreamer_s);
827 return MM_ERROR_RADIO_INVALID_STATE;
829 debug_log("[%s][%05d] GST_STATE_NULL ret_state = %d (GST_STATE_CHANGE_SUCCESS)\n", __func__, __LINE__, ret_state);
835 _mmradio_destroy_pipeline(mm_radio_t * radio)
838 GstStateChangeReturn ret_state;
841 if(gst_element_set_state (radio->pGstreamer_s->pipeline, GST_STATE_NULL) == GST_STATE_CHANGE_FAILURE) {
842 debug_error("Fail to change pipeline state");
843 gst_object_unref (radio->pGstreamer_s->pipeline);
844 g_free (radio->pGstreamer_s);
845 return MM_ERROR_RADIO_INVALID_STATE;
848 ret_state = gst_element_get_state (radio->pGstreamer_s->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
849 if (ret_state == GST_STATE_CHANGE_FAILURE) {
850 debug_error("GST_STATE_CHANGE_FAILURE");
851 gst_object_unref (radio->pGstreamer_s->pipeline);
852 g_free (radio->pGstreamer_s);
853 return MM_ERROR_RADIO_INVALID_STATE;
855 debug_log("[%s][%05d] GST_STATE_NULL ret_state = %d (GST_STATE_CHANGE_SUCCESS)\n", __func__, __LINE__, ret_state);
857 gst_object_unref (radio->pGstreamer_s->pipeline);
858 g_free (radio->pGstreamer_s);
864 _mmradio_seek(mm_radio_t* radio, MMRadioSeekDirectionType direction)
866 MMRADIO_LOG_FENTER();
868 MMRADIO_CHECK_INSTANCE( radio );
869 MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_SEEK );
873 if( _mmradio_mute(radio) != MM_ERROR_NONE)
874 return MM_ERROR_RADIO_NOT_INITIALIZED;
876 MMRADIO_LOG_DEBUG("trying to seek. direction[0:UP/1:DOWN) %d\n", direction);
877 radio->seek_direction = direction;
879 ret = pthread_create(&radio->seek_thread, NULL,
880 (void *)__mmradio_seek_thread, (void *)radio);
884 MMRADIO_LOG_DEBUG("failed create thread\n");
885 return MM_ERROR_RADIO_INTERNAL;
888 MMRADIO_LOG_FLEAVE();
890 return MM_ERROR_NONE;
894 _mmradio_start_scan(mm_radio_t* radio)
896 MMRADIO_LOG_FENTER();
898 MMRADIO_CHECK_INSTANCE( radio );
899 MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_START_SCAN );
903 radio->stop_scan = false;
905 scan_tr_id = pthread_create(&radio->scan_thread, NULL,
906 (void *)__mmradio_scan_thread, (void *)radio);
910 MMRADIO_LOG_DEBUG("failed to create thread : scan\n");
911 return MM_ERROR_RADIO_NOT_INITIALIZED;
914 MMRADIO_SET_STATE( radio, MM_RADIO_STATE_SCANNING );
916 MMRADIO_LOG_FLEAVE();
918 return MM_ERROR_NONE;
922 _mmradio_stop_scan(mm_radio_t* radio)
924 MMRADIO_LOG_FENTER();
926 MMRADIO_CHECK_INSTANCE( radio );
927 MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_STOP_SCAN );
929 radio->stop_scan = true;
931 if( radio->scan_thread > 0 )
933 pthread_cancel(radio->scan_thread);
934 pthread_join(radio->scan_thread, NULL);
935 radio->scan_thread = 0;
938 MMRADIO_SET_STATE( radio, MM_RADIO_STATE_READY );
939 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_STOP, NULL);
941 MMRADIO_LOG_FLEAVE();
943 return MM_ERROR_NONE;
947 _mm_radio_get_signal_strength(mm_radio_t* radio, int *value)
949 MMRADIO_LOG_FENTER();
950 MMRADIO_CHECK_INSTANCE( radio );
952 return_val_if_fail( value, MM_ERROR_INVALID_ARGUMENT );
954 /* just return stored frequency if radio device is not ready */
955 if ( radio->radio_fd < 0 )
957 MMRADIO_LOG_DEBUG("Device not ready so sending 0\n");
959 return MM_ERROR_NONE;
961 if (ioctl(radio->radio_fd, VIDIOC_G_TUNER, &(radio->vt)) < 0)
963 debug_error("ioctl VIDIOC_G_TUNER error\n");
964 return MM_ERROR_RADIO_INTERNAL;
966 *value = radio->vt.signal;
967 MMRADIO_LOG_FLEAVE();
968 return MM_ERROR_NONE;
972 __mmradio_scan_thread(mm_radio_t* radio)
976 char str_error[READ_MAX_BUFFER_SIZE];
978 struct v4l2_hw_freq_seek vs = {0,};
979 vs.tuner = TUNER_INDEX;
980 vs.type = V4L2_TUNER_RADIO;
981 vs.wrap_around = 0; /* around:1 not around:0 */
982 vs.seek_upward = 1; /* up : 1 ------- down : 0 */
984 MMRADIO_LOG_FENTER();
985 MMRADIO_CHECK_INSTANCE_RETURN_VOID( radio );
986 if( _mmradio_mute(radio) != MM_ERROR_NONE)
989 if( _mmradio_set_frequency(radio, radio->region_setting.band_min) != MM_ERROR_NONE)
992 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_START, NULL);
993 MMRADIO_SET_STATE( radio, MM_RADIO_STATE_SCANNING );
995 while( ! radio->stop_scan )
998 MMMessageParamType param = {0,};
1000 MMRADIO_LOG_DEBUG("scanning....\n");
1001 ret = ioctl(radio->radio_fd, VIDIOC_S_HW_FREQ_SEEK, &vs);
1005 if ( errno == EAGAIN )
1007 MMRADIO_LOG_ERROR("scanning timeout\n");
1010 else if ( errno == EINVAL )
1012 MMRADIO_LOG_ERROR("The tuner index is out of bounds or the value in the type field is wrong.");
1017 MMRADIO_LOG_ERROR("Error: %s, %d\n", strerror_r(errno, str_error, sizeof(str_error)), errno);
1022 /* now we can get new frequency from radio device */
1024 if ( radio->stop_scan ) break;
1026 ret = _mmradio_get_frequency(radio, &freq);
1029 MMRADIO_LOG_ERROR("failed to get current frequency\n");
1033 if ( freq < prev_freq )
1035 MMRADIO_LOG_DEBUG("scanning wrapped around. stopping scan\n");
1039 if ( freq == prev_freq)
1042 prev_freq = param.radio_scan.frequency = freq;
1043 MMRADIO_LOG_DEBUG("scanning : new frequency : [%d]\n", param.radio_scan.frequency);
1045 /* drop if max freq is scanned */
1046 if (param.radio_scan.frequency == radio->region_setting.band_max )
1048 MMRADIO_LOG_DEBUG("%d freq is dropping...and stopping scan\n", param.radio_scan.frequency);
1052 if ( radio->stop_scan ) break; // doesn't need to post
1054 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_INFO, ¶m);
1058 radio->scan_thread = 0;
1060 MMRADIO_SET_STATE( radio, MM_RADIO_STATE_READY );
1062 if ( ! radio->stop_scan )
1064 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_FINISH, NULL);
1067 MMRADIO_LOG_FLEAVE();
1075 __is_tunable_frequency(mm_radio_t* radio, int freq)
1077 MMRADIO_LOG_FENTER();
1079 MMRADIO_CHECK_INSTANCE( radio );
1081 if ( freq == radio->region_setting.band_max|| freq == radio->region_setting.band_min )
1084 MMRADIO_LOG_FLEAVE();
1090 __mmradio_seek_thread(mm_radio_t* radio)
1094 char str_error[READ_MAX_BUFFER_SIZE];
1095 bool seek_stop = false;
1096 MMMessageParamType param = {0,};
1097 struct v4l2_hw_freq_seek vs = {0,};
1099 vs.tuner = TUNER_INDEX;
1100 vs.type = V4L2_TUNER_RADIO;
1101 vs.wrap_around = DEFAULT_WRAP_AROUND;
1103 MMRADIO_LOG_FENTER();
1104 MMRADIO_CHECK_INSTANCE_RETURN_VOID( radio );
1106 /* check direction */
1107 switch( radio->seek_direction )
1109 case MM_RADIO_SEEK_UP:
1117 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_START, NULL);
1119 MMRADIO_LOG_DEBUG("seeking....\n");
1121 while ( ! seek_stop )
1123 ret = ioctl( radio->radio_fd, VIDIOC_S_HW_FREQ_SEEK, &vs );
1127 if ( errno == EAGAIN )
1129 /* FIXIT : we need retrying code here */
1130 MMRADIO_LOG_ERROR("scanning timeout\n");
1133 else if ( errno == EINVAL )
1135 MMRADIO_LOG_ERROR("The tuner index is out of bounds or the value in the type field is wrong.");
1140 MMRADIO_LOG_ERROR("Error: %s, %d\n", strerror_r(errno, str_error, sizeof(str_error)), errno);
1145 /* now we can get new frequency from radio device */
1146 ret = _mmradio_get_frequency(radio, &freq);
1149 MMRADIO_LOG_ERROR("failed to get current frequency\n");
1153 MMRADIO_LOG_DEBUG("found frequency\n");
1155 /* if same freq is found, ignore it and search next one. */
1156 if ( freq == radio->prev_seek_freq )
1158 MMRADIO_LOG_DEBUG("It's same with previous found one. So, trying next one. \n");
1162 if ( __is_tunable_frequency(radio, freq) ) // check if it's limit freq or not
1164 /* now tune to new frequency */
1165 ret = _mmradio_set_frequency(radio, freq);
1168 MMRADIO_LOG_ERROR("failed to tune to new frequency\n");
1173 /* now turn on radio
1174 * In the case of limit freq, tuner should be unmuted.
1175 * Otherwise, sound can't output even though application set new frequency.
1177 ret = _mmradio_unmute(radio);
1180 MMRADIO_LOG_ERROR("failed to tune to new frequency\n");
1184 param.radio_scan.frequency = radio->prev_seek_freq = freq;
1185 MMRADIO_LOG_DEBUG("seeking : new frequency : [%d]\n", param.radio_scan.frequency);
1186 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, ¶m);
1190 radio->seek_thread = 0;
1192 MMRADIO_LOG_FLEAVE();
1198 /* freq -1 means it's failed to seek */
1199 param.radio_scan.frequency = -1;
1200 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, ¶m);
1206 __mmradio_post_message(mm_radio_t* radio, enum MMMessageType msgtype, MMMessageParamType* param)
1208 MMRADIO_CHECK_INSTANCE( radio );
1210 MMRADIO_LOG_FENTER();
1212 if ( !radio->msg_cb )
1214 debug_warning("failed to post a message\n");
1218 MMRADIO_LOG_DEBUG("address of msg_cb : %d\n", radio->msg_cb);
1220 radio->msg_cb(msgtype, param, radio->msg_cb_param);
1222 MMRADIO_LOG_FLEAVE();
1228 __mmradio_check_state(mm_radio_t* radio, MMRadioCommand command)
1230 MMRadioStateType radio_state = MM_RADIO_STATE_NUM;
1232 MMRADIO_LOG_FENTER();
1234 MMRADIO_CHECK_INSTANCE( radio );
1236 radio_state = __mmradio_get_state( radio );
1238 MMRADIO_LOG_DEBUG("incomming command : %d current state : %d\n", command, radio_state);
1242 case MMRADIO_COMMAND_CREATE:
1244 if ( radio_state != 0 )
1249 case MMRADIO_COMMAND_REALIZE:
1251 if ( radio_state == MM_RADIO_STATE_READY ||
1252 radio_state == MM_RADIO_STATE_PLAYING ||
1253 radio_state == MM_RADIO_STATE_SCANNING )
1256 if ( radio_state == 0 )
1261 case MMRADIO_COMMAND_UNREALIZE:
1263 if ( radio_state == MM_RADIO_STATE_NULL )
1266 /* we can call unrealize at any higher state */
1270 case MMRADIO_COMMAND_START:
1272 if ( radio_state == MM_RADIO_STATE_PLAYING )
1275 if ( radio_state != MM_RADIO_STATE_READY )
1280 case MMRADIO_COMMAND_STOP:
1282 if ( radio_state == MM_RADIO_STATE_READY )
1285 if ( radio_state != MM_RADIO_STATE_PLAYING )
1290 case MMRADIO_COMMAND_START_SCAN:
1292 if ( radio_state == MM_RADIO_STATE_SCANNING )
1295 if ( radio_state != MM_RADIO_STATE_READY )
1300 case MMRADIO_COMMAND_STOP_SCAN:
1302 if ( radio_state == MM_RADIO_STATE_READY )
1305 if ( radio_state != MM_RADIO_STATE_SCANNING )
1310 case MMRADIO_COMMAND_DESTROY:
1311 case MMRADIO_COMMAND_MUTE:
1312 case MMRADIO_COMMAND_UNMUTE:
1313 case MMRADIO_COMMAND_SET_FREQ:
1314 case MMRADIO_COMMAND_GET_FREQ:
1315 case MMRADIO_COMMAND_SET_REGION:
1317 /* we can do it at any state */
1321 case MMRADIO_COMMAND_SEEK:
1323 if ( radio_state != MM_RADIO_STATE_PLAYING )
1328 case MMRADIO_COMMAND_GET_REGION:
1330 if ( radio_state == MM_RADIO_STATE_NULL )
1336 MMRADIO_LOG_DEBUG("not handled in FSM. don't care it\n");
1340 MMRADIO_LOG_DEBUG("status OK\n");
1342 radio->cmd = command;
1344 MMRADIO_LOG_FLEAVE();
1346 return MM_ERROR_NONE;
1350 debug_warning("invalid state. current : %d command : %d\n",
1351 radio_state, command);
1352 MMRADIO_LOG_FLEAVE();
1353 return MM_ERROR_RADIO_INVALID_STATE;
1357 debug_warning("mm-radio is in the desired state(%d). doing noting\n", radio_state);
1358 MMRADIO_LOG_FLEAVE();
1359 return MM_ERROR_RADIO_NO_OP;
1364 __mmradio_set_state(mm_radio_t* radio, int new_state)
1366 MMMessageParamType msg = {0, };
1367 int msg_type = MM_MESSAGE_UNKNOWN;
1369 MMRADIO_LOG_FENTER();
1370 MMRADIO_CHECK_INSTANCE( radio );
1374 debug_warning("calling set_state with invalid radio handle\n");
1378 if ( radio->current_state == new_state && radio->pending_state == 0 )
1380 debug_warning("we are in same state\n");
1385 radio->old_state = radio->current_state;
1386 radio->current_state = new_state;
1388 /* fill message param */
1389 msg.state.previous = radio->old_state;
1390 msg.state.current = radio->current_state;
1392 /* post message to application */
1393 switch( radio->sm.by_asm_cb )
1395 case MMRADIO_ASM_CB_NONE:
1397 msg_type = MM_MESSAGE_STATE_CHANGED;
1398 MMRADIO_POST_MSG( radio, msg_type, &msg );
1402 case MMRADIO_ASM_CB_POSTMSG:
1404 msg_type = MM_MESSAGE_STATE_INTERRUPTED;
1405 msg.union_type = MM_MSG_UNION_CODE;
1406 msg.code = radio->sm.event_src;
1407 MMRADIO_POST_MSG( radio, msg_type, &msg );
1411 case MMRADIO_ASM_CB_SKIP_POSTMSG:
1416 MMRADIO_LOG_FLEAVE();
1422 __mmradio_get_state(mm_radio_t* radio)
1424 MMRADIO_CHECK_INSTANCE( radio );
1426 MMRADIO_LOG_DEBUG("radio state : current : [%d] old : [%d] pending : [%d]\n",
1427 radio->current_state, radio->old_state, radio->pending_state );
1429 return radio->current_state;
1432 void _mmradio_sound_focus_cb(int id, mm_sound_focus_type_e focus_type,
1433 mm_sound_focus_state_e focus_state, const char *reason_for_change,
1434 const char *additional_info, void *user_data)
1436 mm_radio_t *radio = (mm_radio_t *) user_data;
1437 ASM_event_sources_t event_source;
1438 int result = MM_ERROR_NONE;
1439 int postMsg = false;
1441 MMRADIO_LOG_FENTER();
1442 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1444 mmradio_get_audio_focus_reason(focus_state, reason_for_change, &event_source, &postMsg);
1445 radio->sm.event_src = event_source;
1447 switch (focus_state) {
1448 case FOCUS_IS_RELEASED:
1449 radio->sm.by_asm_cb = MMRADIO_ASM_CB_POSTMSG;
1450 result = _mmradio_stop(radio);
1452 MMRADIO_LOG_ERROR("failed to stop radio\n");
1454 MMRADIO_LOG_DEBUG("FOCUS_IS_RELEASED\n");
1457 case FOCUS_IS_ACQUIRED: {
1458 MMMessageParamType msg = {0,};
1459 msg.union_type = MM_MSG_UNION_CODE;
1460 msg.code = event_source;
1462 MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg);
1464 radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE;
1466 MMRADIO_LOG_DEBUG("FOCUS_IS_ACQUIRED\n");
1471 MMRADIO_LOG_DEBUG("Unknown focus_state\n");
1474 MMRADIO_LOG_FLEAVE();
1477 void _mmradio_sound_focus_watch_cb(int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e focus_state,
1478 const char *reason_for_change, const char *additional_info, void *user_data)
1480 mm_radio_t *radio = (mm_radio_t *) user_data;
1481 ASM_event_sources_t event_source;
1482 int result = MM_ERROR_NONE;
1483 int postMsg = false;
1485 MMRADIO_LOG_FENTER();
1486 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1488 mmradio_get_audio_focus_reason(!focus_state, reason_for_change, &event_source, &postMsg);
1489 radio->sm.event_src = event_source;
1491 switch (focus_state) {
1492 case FOCUS_IS_RELEASED: {
1493 MMMessageParamType msg = {0,};
1494 msg.union_type = MM_MSG_UNION_CODE;
1495 msg.code = event_source;
1497 MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg);
1499 radio->sm.by_asm_cb = MMRADIO_ASM_CB_NONE;
1501 MMRADIO_LOG_DEBUG("FOCUS_IS_ACQUIRED postMsg: %d\n", postMsg);
1505 case FOCUS_IS_ACQUIRED: {
1506 radio->sm.by_asm_cb = MMRADIO_ASM_CB_POSTMSG;
1507 result = _mmradio_stop(radio);
1509 MMRADIO_LOG_ERROR("failed to stop radio\n");
1511 MMRADIO_LOG_DEBUG("FOCUS_IS_RELEASED\n");
1517 MMRADIO_LOG_DEBUG("Unknown focus_state postMsg : %d\n", postMsg);
1520 MMRADIO_LOG_FLEAVE();
1523 __mmradio_device_connected_cb(MMSoundDevice_t device, bool is_connected, void *user_data)
1525 mm_radio_t *radio = (mm_radio_t *) user_data;
1526 int result = MM_ERROR_NONE;
1527 mm_sound_device_type_e type;
1529 MMRADIO_LOG_FENTER();
1530 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1532 if (mm_sound_get_device_type (device, &type) != MM_ERROR_NONE)
1534 debug_error("getting device type failed");
1540 case MM_SOUND_DEVICE_TYPE_AUDIOJACK:
1541 case MM_SOUND_DEVICE_TYPE_BLUETOOTH:
1542 case MM_SOUND_DEVICE_TYPE_HDMI:
1543 case MM_SOUND_DEVICE_TYPE_MIRRORING:
1544 case MM_SOUND_DEVICE_TYPE_USB_AUDIO:
1547 MMRADIO_LOG_ERROR("sound device unplugged");
1548 radio->sm.by_asm_cb = MMRADIO_ASM_CB_POSTMSG;
1549 radio->sm.event_src = ASM_EVENT_SOURCE_EARJACK_UNPLUG;
1551 result = _mmradio_stop(radio);
1552 if (result != MM_ERROR_NONE)
1554 MMRADIO_LOG_ERROR("failed to stop radio\n");
1562 MMRADIO_LOG_FLEAVE();
1565 int _mmradio_get_region_type(mm_radio_t*radio, MMRadioRegionType *type)
1567 MMRADIO_LOG_FENTER();
1568 MMRADIO_CHECK_INSTANCE( radio );
1569 MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_GET_REGION );
1571 return_val_if_fail( type, MM_ERROR_INVALID_ARGUMENT );
1573 *type = radio->region_setting.country;
1575 MMRADIO_LOG_FLEAVE();
1576 return MM_ERROR_NONE;
1579 int _mmradio_get_region_frequency_range(mm_radio_t* radio, unsigned int *min_freq, unsigned int *max_freq)
1581 MMRADIO_LOG_FENTER();
1582 MMRADIO_CHECK_INSTANCE( radio );
1583 MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_GET_REGION );
1585 return_val_if_fail( min_freq && max_freq, MM_ERROR_INVALID_ARGUMENT );
1587 *min_freq = radio->region_setting.band_min;
1588 *max_freq = radio->region_setting.band_max;
1590 MMRADIO_LOG_FLEAVE();
1591 return MM_ERROR_NONE;
1594 int _mmradio_get_channel_spacing(mm_radio_t* radio, unsigned int *ch_spacing)
1596 MMRADIO_LOG_FENTER();
1597 MMRADIO_CHECK_INSTANCE( radio );
1598 MMRADIO_CHECK_STATE_RETURN_IF_FAIL( radio, MMRADIO_COMMAND_GET_REGION );
1600 return_val_if_fail( ch_spacing, MM_ERROR_INVALID_ARGUMENT );
1602 *ch_spacing = radio->region_setting.channel_spacing;
1604 MMRADIO_LOG_FLEAVE();
1605 return MM_ERROR_NONE;