4 * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
20 /*===========================================================================================
24 ========================================================================================== */
32 #include <sys/ioctl.h>
37 #include <mm_message.h>
40 #include "mm_radio_priv_hal.h"
42 /*===========================================================================================
43 LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE
44 ========================================================================================== */
45 /*---------------------------------------------------------------------------
46 GLOBAL CONSTANT DEFINITIONS:
47 ---------------------------------------------------------------------------*/
49 /*---------------------------------------------------------------------------
50 IMPORTED VARIABLE DECLARATIONS:
51 ---------------------------------------------------------------------------*/
53 /*---------------------------------------------------------------------------
54 IMPORTED FUNCTION DECLARATIONS:
55 ---------------------------------------------------------------------------*/
57 /*---------------------------------------------------------------------------
59 ---------------------------------------------------------------------------*/
60 #define DEFAULT_DEVICE "/dev/radio0"
63 #define DEFAULT_FREQ 107700
66 #define RADIO_FREQ_FORMAT_SET(x_freq) ((x_freq) * FREQ_FRAC)
67 #define RADIO_FREQ_FORMAT_GET(x_freq) ((x_freq) / FREQ_FRAC)
68 /* If non-zero, wrap around when at the end of the frequency range, else stop seeking */
69 #define DEFAULT_WRAP_AROUND 1
71 #define RADIO_DEFAULT_REGION MM_RADIO_REGION_GROUP_USA
72 #define READ_MAX_BUFFER_SIZE 1024
73 #define DEFAULT_MAX_MEDIA_VOLUME 15
74 /*---------------------------------------------------------------------------
75 LOCAL CONSTANT DEFINITIONS:
76 ---------------------------------------------------------------------------*/
78 /*---------------------------------------------------------------------------
79 LOCAL DATA TYPE DEFINITIONS:
80 ---------------------------------------------------------------------------*/
82 /*---------------------------------------------------------------------------
83 GLOBAL VARIABLE DEFINITIONS:
84 ---------------------------------------------------------------------------*/
87 /*---------------------------------------------------------------------------
88 LOCAL VARIABLE DEFINITIONS:
89 ---------------------------------------------------------------------------*/
90 /* radio region configuration table */
91 static const MMRadioRegion_t region_table[] = {
92 { /* Notrh America, South America, South Korea, Taiwan, Australia */
93 MM_RADIO_REGION_GROUP_USA, /* region type */
94 MM_RADIO_DEEMPHASIS_75_US, /* de-emphasis */
95 MM_RADIO_FREQ_MIN_87500_KHZ, /* min freq. */
96 MM_RADIO_FREQ_MAX_108000_KHZ, /* max freq. */
99 { /* China, Europe, Africa, Middle East, Hong Kong, India, Indonesia, Russia, Singapore */
100 MM_RADIO_REGION_GROUP_EUROPE,
101 MM_RADIO_DEEMPHASIS_50_US,
102 MM_RADIO_FREQ_MIN_87500_KHZ,
103 MM_RADIO_FREQ_MAX_108000_KHZ,
107 MM_RADIO_REGION_GROUP_JAPAN,
108 MM_RADIO_DEEMPHASIS_50_US,
109 MM_RADIO_FREQ_MIN_76100_KHZ,
110 MM_RADIO_FREQ_MAX_89900_KHZ,
115 /*---------------------------------------------------------------------------
116 LOCAL FUNCTION PROTOTYPES:
117 ---------------------------------------------------------------------------*/
118 static bool __mmradio_post_message(mm_radio_t *radio, enum MMMessageType msgtype, MMMessageParamType *param);
119 static int __mmradio_check_state(mm_radio_t *radio, MMRadioCommand command);
120 static int __mmradio_get_state(mm_radio_t *radio);
121 static bool __mmradio_set_state(mm_radio_t *radio, int new_state);
122 void _mmradio_seek_cancel(mm_radio_t *radio);
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_create_thread(mm_radio_t *radio);
127 static void __mmradio_destroy_thread(mm_radio_t *radio);
129 static void __mmradio_volume_changed_cb(volume_type_t type, unsigned int volume, void *user_data);
130 static int __mmradio_set_media_volume(mm_radio_t *radio, unsigned int level);
131 static int __resource_release_cb(mm_resource_manager_h rm,
132 mm_resource_manager_res_h res, void *user_data);
134 int _mmradio_apply_region(mm_radio_t *radio, MMRadioRegionType region, bool update)
136 int ret = MM_ERROR_NONE;
140 MMRADIO_LOG_FENTER();
142 MMRADIO_CHECK_INSTANCE(radio);
143 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_REGION);
145 /* if needed, radio region must be updated.
146 * Otherwise, just applying settings to device without it.
149 count = ARRAY_SIZE(region_table);
151 /* TODO: if auto is supported...get the region info. here */
153 /* update radio region settings */
154 for (index = 0; index < count; index++) {
155 /* find the region from pre-defined table */
156 if (region_table[index].country == region) {
157 radio->region_setting.country = region_table[index].country;
158 radio->region_setting.deemphasis = region_table[index].deemphasis;
159 radio->region_setting.band_min = region_table[index].band_min;
160 radio->region_setting.band_max = region_table[index].band_max;
161 radio->region_setting.channel_spacing = region_table[index].channel_spacing;
166 MMRADIO_LOG_INFO("setting region - country: %d, de-emphasis: %d, band range: %d ~ %d KHz",
167 radio->region_setting.country, radio->region_setting.deemphasis,
168 radio->region_setting.band_min, radio->region_setting.band_max);
170 MMRADIO_LOG_FLEAVE();
175 int _mmradio_create_radio(mm_radio_t *radio)
177 int ret = MM_ERROR_NONE;
179 MMRADIO_LOG_FENTER();
181 MMRADIO_CHECK_INSTANCE(radio);
182 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_CREATE);
184 /* set default value */
185 radio->freq = DEFAULT_FREQ;
186 memset(&radio->region_setting, 0, sizeof(MMRadioRegion_t));
187 radio->local_volume = 1.0;
189 /* create mutex and thread */
190 ret = __mmradio_create_thread(radio);
192 MMRADIO_LOG_ERROR("failed to create threads");
196 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_NULL);
198 /* initialize resource manager */
199 ret = mm_resource_manager_create(MM_RESOURCE_MANAGER_APP_CLASS_MEDIA,
200 __resource_release_cb, radio, &radio->resource_manager);
202 MMRADIO_LOG_ERROR("failed to create resource manager");
203 return MM_ERROR_RADIO_INTERNAL;
206 ret = radio_hal_interface_init(&(radio->hal_inf));
208 MMRADIO_LOG_ERROR("failed to init mmradio hal interface");
212 MMRADIO_LOG_FLEAVE();
214 return MM_ERROR_NONE;
217 int _mmradio_realize(mm_radio_t *radio)
219 int ret = MM_ERROR_NONE;
223 MMRadioRegionType region = MM_RADIO_REGION_GROUP_NONE;
225 MMRADIO_LOG_FENTER();
227 MMRADIO_CHECK_INSTANCE(radio);
228 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_REALIZE);
230 if (radio->region_setting.country == MM_RADIO_REGION_GROUP_NONE) {
231 /* not initialized yet. set it with default region */
232 region = RADIO_DEFAULT_REGION;
235 /* already initialized by application */
236 region = radio->region_setting.country;
239 ret = _mmradio_apply_region(radio, region, update);
241 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
242 ret = sound_manager_create_stream_information_internal(SOUND_STREAM_TYPE_RADIO, NULL, radio, &radio->stream_info);
243 if (ret != MM_ERROR_NONE) {
244 MMRADIO_LOG_ERROR("failed to create stream information");
245 MMRADIO_LOG_FLEAVE();
248 ret = sound_manager_create_virtual_stream(radio->stream_info, &radio->vstream);
249 if (ret != MM_ERROR_NONE) {
250 MMRADIO_LOG_ERROR("sound_manager_create_virtual_stream error");
251 MMRADIO_LOG_FLEAVE();
256 ret = sound_manager_get_max_volume(SOUND_TYPE_MEDIA, &max);
257 if (ret != MM_ERROR_NONE) {
258 MMRADIO_LOG_WARNING("failed to get max volume");
259 radio->max_media_volume = DEFAULT_MAX_MEDIA_VOLUME;
261 radio->max_media_volume = max;
264 ret = mm_sound_volume_get_value(VOLUME_TYPE_MEDIA, &volume);
266 if (ret != MM_ERROR_NONE)
267 MMRADIO_LOG_WARNING("failed to get media volume");
269 MMRADIO_VOLUME_LOCK(radio);
270 radio->media_volume = volume;
271 MMRADIO_VOLUME_UNLOCK(radio);
273 ret = mm_sound_add_volume_changed_callback(__mmradio_volume_changed_cb, (void *)radio, &radio->volume_subs_id);
274 if (ret != MM_ERROR_NONE)
275 MMRADIO_LOG_WARNING("failed to register volume changed callback");
277 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
279 MMRADIO_LOG_FLEAVE();
281 return MM_ERROR_NONE;
284 int _mmradio_unrealize(mm_radio_t *radio)
286 int ret = MM_ERROR_NONE;
288 MMRADIO_LOG_FENTER();
290 MMRADIO_CHECK_INSTANCE(radio);
291 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_UNREALIZE);
293 ret = mm_sound_remove_volume_changed_callback(radio->volume_subs_id);
294 if (ret != MM_ERROR_NONE)
295 MMRADIO_LOG_WARNING("mm_sound_remove_volume_changed_callback error");
297 /*Finish if there are scans*/
298 _mmradio_stop_scan(radio);
300 /*Stop radio if started*/
301 _mmradio_stop(radio);
303 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
304 sound_manager_destroy_virtual_stream(radio->vstream);
305 sound_manager_destroy_stream_information(radio->stream_info);
308 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_NULL);
310 MMRADIO_LOG_FLEAVE();
315 int _mmradio_destroy(mm_radio_t *radio)
317 int ret = MM_ERROR_NONE;
318 MMRADIO_LOG_FENTER();
320 MMRADIO_CHECK_INSTANCE(radio);
321 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_DESTROY);
323 _mmradio_unrealize(radio);
325 /* destroy mutex and thread */
326 __mmradio_destroy_thread(radio);
328 ret = radio_hal_interface_deinit(radio->hal_inf);
330 MMRADIO_LOG_ERROR("failed to deinitialize radio hal interface");
334 ret = mm_resource_manager_destroy(radio->resource_manager);
336 MMRADIO_LOG_ERROR("failed to destroy resource manager");
337 return MM_ERROR_RADIO_INTERNAL;
340 MMRADIO_LOG_FLEAVE();
342 return MM_ERROR_NONE;
345 /* unit should be KHz */
346 int _mmradio_set_frequency(mm_radio_t *radio, int freq)
348 int ret = MM_ERROR_NONE;
350 MMRADIO_LOG_FENTER();
352 MMRADIO_CHECK_INSTANCE(radio);
353 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_FREQ);
355 MMRADIO_LOG_INFO("Setting %d frequency", freq);
359 ret = radio_hal_set_frequency(radio->hal_inf, freq);
360 if (ret != MM_ERROR_NONE) {
361 MMRADIO_LOG_ERROR("failed to set radio hal frequency");
362 MMRADIO_LOG_FLEAVE();
366 MMRADIO_LOG_FLEAVE();
372 int _mmradio_get_frequency(mm_radio_t *radio, int *pFreq)
374 int ret = MM_ERROR_NONE;
376 MMRADIO_LOG_FENTER();
378 MMRADIO_CHECK_INSTANCE(radio);
379 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_FREQ);
381 MMRADIO_RETURN_VAL_IF_FAIL(pFreq, MM_ERROR_INVALID_ARGUMENT);
383 ret = radio_hal_get_frequency(radio->hal_inf, &freq);
384 if (ret != MM_ERROR_NONE) {
385 MMRADIO_LOG_ERROR("failed to get radio hal frequency");
390 /* update freq in handle */
391 MMRADIO_LOG_INFO("Updating %d frequency", freq);
394 *pFreq = (int)radio->freq;
396 MMRADIO_LOG_FLEAVE();
401 int _mmradio_mute(mm_radio_t *radio)
403 int ret = MM_ERROR_NONE;
404 MMRADIO_LOG_FENTER();
406 MMRADIO_CHECK_INSTANCE(radio);
407 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_MUTE);
409 ret = radio_hal_mute(radio->hal_inf);
410 if (ret == MM_ERROR_NOT_SUPPORT_API) {
411 MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
412 } else if (ret != MM_ERROR_NONE) {
413 MMRADIO_LOG_ERROR("failed to set radio hal mute");
414 MMRADIO_LOG_FLEAVE();
418 radio->is_muted = true;
419 MMRADIO_LOG_INFO("Radio mute state [%d]", radio->is_muted);
420 MMRADIO_LOG_FLEAVE();
425 int _mmradio_unmute(mm_radio_t *radio)
427 int ret = MM_ERROR_NONE;
428 MMRADIO_LOG_FENTER();
430 MMRADIO_CHECK_INSTANCE(radio);
431 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_UNMUTE);
433 ret = radio_hal_unmute(radio->hal_inf);
434 if (ret == MM_ERROR_NOT_SUPPORT_API) {
435 MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
436 } else if (ret != MM_ERROR_NONE) {
437 MMRADIO_LOG_ERROR("failed to set radio hal unmute");
438 MMRADIO_LOG_FLEAVE();
442 radio->is_muted = false;
443 MMRADIO_LOG_INFO("Radio mute state [%d]", radio->is_muted);
444 MMRADIO_LOG_FLEAVE();
449 int _mmradio_set_message_callback(mm_radio_t *radio, MMMessageCallback callback, void *user_param)
451 MMRADIO_LOG_FENTER();
453 MMRADIO_CHECK_INSTANCE(radio);
455 radio->msg_cb = callback;
456 radio->msg_cb_param = user_param;
458 MMRADIO_LOG_DEBUG("msg_cb : 0x%x msg_cb_param : 0x%x", callback, user_param);
460 MMRADIO_LOG_FLEAVE();
462 return MM_ERROR_NONE;
465 int _mmradio_get_state(mm_radio_t *radio, int *pState)
469 MMRADIO_LOG_FENTER();
471 MMRADIO_CHECK_INSTANCE(radio);
472 MMRADIO_RETURN_VAL_IF_FAIL(pState, MM_ERROR_INVALID_ARGUMENT);
474 state = __mmradio_get_state(radio);
478 MMRADIO_LOG_FLEAVE();
480 return MM_ERROR_NONE;
483 int _mmradio_start(mm_radio_t *radio)
485 int ret = MM_ERROR_NONE;
486 unsigned int volume = 0;
488 MMRADIO_LOG_FENTER();
490 MMRADIO_CHECK_INSTANCE(radio);
491 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_START);
493 MMRADIO_LOG_INFO("now tune to frequency : %d", radio->freq);
495 if (!radio->is_ready) {
496 ret = mm_resource_manager_mark_for_acquire(radio->resource_manager,
497 MM_RESOURCE_MANAGER_RES_TYPE_RADIO,
498 MM_RESOURCE_MANAGER_RES_VOLUME_FULL, &radio->radio_resource);
499 if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
500 MMRADIO_LOG_ERROR("resource manager mark for acquire fail");
501 return MM_ERROR_RADIO_INTERNAL;
504 radio->interrupted_by_resource_conflict = FALSE;
505 ret = mm_resource_manager_commit(radio->resource_manager);
506 if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
507 MMRADIO_LOG_ERROR("failed to commit resource manager");
508 mm_resource_manager_mark_for_release(radio->resource_manager,
509 radio->radio_resource);
510 radio->radio_resource = NULL;
514 ret = radio_hal_prepare(radio->hal_inf);
515 if (ret == MM_ERROR_NOT_SUPPORT_API) {
516 MMRADIO_LOG_WARNING("radio_hal_prepare is not supported");
517 } else if (ret != MM_ERROR_NONE) {
518 MMRADIO_LOG_ERROR("failed to prepare radio hal");
522 ret = radio_hal_open(radio->hal_inf);
523 if (ret == MM_ERROR_NOT_SUPPORT_API) {
524 MMRADIO_LOG_WARNING("radio_hal_open is not supported");
525 } else if (ret != MM_ERROR_NONE) {
526 MMRADIO_LOG_ERROR("failed to open radio hal");
529 radio->is_ready = true;
531 MMRADIO_LOG_DEBUG("radio prepared and opened");
534 ret = mm_sound_volume_get_value(VOLUME_TYPE_MEDIA, &volume);
535 if (ret != MM_ERROR_NONE)
536 MMRADIO_LOG_WARNING("failed to get media volume");
538 ret = __mmradio_set_media_volume(radio, volume);
539 if (ret != MM_ERROR_NONE) {
540 MMRADIO_LOG_ERROR("failed to set media volume");
544 ret = radio_hal_start(radio->hal_inf);
545 if (ret == MM_ERROR_NOT_SUPPORT_API) {
546 MMRADIO_LOG_WARNING("radio_hal_start is not supported");
548 MMRADIO_LOG_ERROR("failed to start radio hal");
552 /* set stored frequency */
553 ret = radio_hal_set_frequency(radio->hal_inf, radio->freq);
555 MMRADIO_LOG_ERROR("failed to set radio hal frequency");
559 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
560 ret = sound_manager_start_virtual_stream(radio->vstream);
562 MMRADIO_LOG_ERROR("failed to start sound manager virtual stream");
567 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_PLAYING);
569 MMRADIO_LOG_FLEAVE();
571 return MM_ERROR_NONE;
574 radio_hal_close(radio->hal_inf);
576 radio_hal_unprepare(radio->hal_inf);
577 radio->is_ready = false;
581 int _mmradio_stop(mm_radio_t *radio)
583 int ret = MM_ERROR_NONE;
585 MMRADIO_LOG_FENTER();
587 MMRADIO_CHECK_INSTANCE(radio);
588 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_STOP);
590 /*cancel if any seek*/
591 _mmradio_seek_cancel(radio);
592 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
593 ret = sound_manager_stop_virtual_stream(radio->vstream);
594 if (ret != MM_ERROR_NONE) {
595 MMRADIO_LOG_ERROR("failed to stop virtual_stream");
600 ret = radio_hal_stop(radio->hal_inf);
601 if (ret == MM_ERROR_NOT_SUPPORT_API) {
602 MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
604 MMRADIO_LOG_ERROR("failed to stop radio hal");
608 if (radio->is_ready) {
609 /* close radio device here !!!! */
610 ret = radio_hal_close(radio->hal_inf);
611 if (ret == MM_ERROR_NOT_SUPPORT_API) {
612 MMRADIO_LOG_WARNING("radio_hal_close is not supported");
613 } else if (ret != MM_ERROR_NONE) {
614 MMRADIO_LOG_ERROR("failed to close radio hal");
618 ret = radio_hal_unprepare(radio->hal_inf);
619 if (ret == MM_ERROR_NOT_SUPPORT_API) {
620 MMRADIO_LOG_WARNING("radio_hal_unprepare is not supported");
621 } else if (ret != MM_ERROR_NONE) {
622 MMRADIO_LOG_ERROR("failed to unprepare radio hal");
626 if (!radio->interrupted_by_resource_conflict && /* is being released */
627 radio->radio_resource != NULL) {
628 ret = mm_resource_manager_mark_for_release(radio->resource_manager,
629 radio->radio_resource);
630 radio->radio_resource = NULL;
631 if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
632 MMRADIO_LOG_ERROR("failed to mark resource for release, ret(0x%x)", ret);
636 ret = mm_resource_manager_commit(radio->resource_manager);
637 if (ret != MM_RESOURCE_MANAGER_ERROR_NONE)
638 MMRADIO_LOG_ERROR("resource manager commit fail");
641 radio->is_ready = false;
644 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
646 MMRADIO_LOG_FLEAVE();
648 return MM_ERROR_NONE;
651 int _mmradio_seek(mm_radio_t *radio, MMRadioSeekDirectionType direction)
653 int ret = MM_ERROR_NONE;
655 MMRADIO_LOG_FENTER();
657 MMRADIO_CHECK_INSTANCE(radio);
658 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SEEK);
660 if (radio->seek.is_running) {
661 MMRADIO_LOG_ERROR("[RADIO_ERROR_INVALID_OPERATION]radio is seeking, can't serve another request try again");
662 return MM_ERROR_RADIO_INTERNAL;
665 radio->seek_unmute = false;
667 if (!radio->is_muted) {
668 ret = radio_hal_mute(radio->hal_inf);
669 if (ret == MM_ERROR_NOT_SUPPORT_API) {
670 MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
672 MMRADIO_LOG_ERROR("failed to set radio hal mute");
675 radio->seek_unmute = true;
678 MMRADIO_LOG_INFO("trying to seek. direction[0:UP/1:DOWN) %d", direction);
679 radio->seek_direction = direction;
680 radio->seek.is_running = true;
681 radio->seek.stop = false;
683 MMRADIO_SEEK_THREAD_SIGNAL(radio);
685 MMRADIO_LOG_FLEAVE();
687 return MM_ERROR_NONE;
690 void _mmradio_seek_cancel(mm_radio_t *radio)
692 MMRADIO_LOG_FENTER();
694 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
696 /* cancel any outstanding seek request */
697 radio->seek.stop = true;
699 MMRADIO_LOG_FLEAVE();
702 int _mmradio_start_scan(mm_radio_t *radio)
704 int ret = MM_ERROR_NONE;
706 MMRADIO_LOG_FENTER();
708 MMRADIO_CHECK_INSTANCE(radio);
709 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_START_SCAN);
711 radio->scan.stop = false;
713 if (!radio->is_ready) {
714 ret = mm_resource_manager_mark_for_acquire(radio->resource_manager,
715 MM_RESOURCE_MANAGER_RES_TYPE_RADIO,
716 MM_RESOURCE_MANAGER_RES_VOLUME_FULL, &radio->radio_resource);
717 if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
718 MMRADIO_LOG_ERROR("resource manager mark for acquire fail");
719 return MM_ERROR_RADIO_INTERNAL;
722 radio->interrupted_by_resource_conflict = FALSE;
723 ret = mm_resource_manager_commit(radio->resource_manager);
724 if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
725 MMRADIO_LOG_ERROR("failed to commit resource manager");
726 mm_resource_manager_mark_for_release(radio->resource_manager,
727 radio->radio_resource);
728 radio->radio_resource = NULL;
732 ret = radio_hal_prepare(radio->hal_inf);
733 if (ret == MM_ERROR_NOT_SUPPORT_API) {
734 MMRADIO_LOG_WARNING("radio_hal_prepare is not supported");
735 } else if (ret != MM_ERROR_NONE) {
736 MMRADIO_LOG_ERROR("failed to prepare radio hal");
740 ret = radio_hal_open(radio->hal_inf);
741 if (ret == MM_ERROR_NOT_SUPPORT_API) {
742 MMRADIO_LOG_WARNING("radio_hal_open is not supported");
743 } else if (ret != MM_ERROR_NONE) {
744 MMRADIO_LOG_ERROR("failed to open radio hal");
745 MMRADIO_LOG_FLEAVE();
748 radio->is_ready = true;
750 MMRADIO_LOG_DEBUG("radio prepared and opened");
753 radio->scan.is_running = true;
755 MMRADIO_SCAN_THREAD_SIGNAL(radio);
757 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_SCANNING);
759 MMRADIO_LOG_FLEAVE();
761 return MM_ERROR_NONE;
764 int _mmradio_stop_scan(mm_radio_t *radio)
766 MMRADIO_LOG_FENTER();
768 MMRADIO_CHECK_INSTANCE(radio);
769 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_STOP_SCAN);
771 radio->scan.stop = true;
773 MMRADIO_LOG_FLEAVE();
775 return MM_ERROR_NONE;
778 int _mm_radio_get_signal_strength(mm_radio_t *radio, int *value)
780 int ret = MM_ERROR_NONE;
781 int32_t strength = 0;
782 MMRADIO_LOG_FENTER();
783 MMRADIO_CHECK_INSTANCE(radio);
785 MMRADIO_RETURN_VAL_IF_FAIL(value, MM_ERROR_INVALID_ARGUMENT);
787 /* just return stored frequency if radio device is not ready */
788 ret = radio_hal_get_signal_strength(radio->hal_inf, &strength);
789 if (ret == MM_ERROR_NOT_SUPPORT_API) {
790 MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
791 } else if (ret != MM_ERROR_NONE) {
792 MMRADIO_LOG_ERROR("failed to get radio hal signal strength");
794 MMRADIO_LOG_FLEAVE();
797 *value = (int)strength;
798 MMRADIO_LOG_FLEAVE();
799 return MM_ERROR_NONE;
802 void __mmradio_scan_thread(mm_radio_t *radio)
804 int ret = MM_ERROR_NONE;
807 MMRADIO_LOG_FENTER();
808 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
810 MMRADIO_SCAN_THREAD_LOCK(radio);
812 while (!radio->scan.thread_exit) {
813 MMRADIO_LOG_DEBUG("scan thread started. waiting for signal.");
814 MMRADIO_SCAN_THREAD_WAIT(radio);
816 if (radio->scan.thread_exit) {
817 MMRADIO_LOG_DEBUG("exiting scan thread");
821 ret = radio_hal_mute(radio->hal_inf);
822 if (ret == MM_ERROR_NOT_SUPPORT_API) {
823 MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
824 } else if (ret != MM_ERROR_NONE) {
825 MMRADIO_LOG_ERROR("faied to set radio hal mute");
829 ret = radio_hal_set_frequency(radio->hal_inf, radio->region_setting.band_min);
830 if (ret != MM_ERROR_NONE)
833 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_START, NULL);
834 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_SCANNING);
836 while (!radio->scan.stop) {
839 MMMessageParamType param = { 0, };
841 MMRADIO_LOG_DEBUG("scanning....");
843 if (radio->scan.thread_exit) {
844 MMRADIO_LOG_DEBUG("exiting scan thread");
848 if (radio->scan.stop) {
849 MMRADIO_LOG_INFO("scan was canceled");
853 MMRADIO_HAL_SEEK_THREAD_LOCK(radio);
854 ret = radio_hal_seek(radio->hal_inf, MM_RADIO_SEEK_UP);
855 MMRADIO_HAL_SEEK_THREAD_UNLOCK(radio);
856 if (ret != MM_ERROR_NONE) {
857 MMRADIO_LOG_ERROR("radio scanning error");
861 if (radio->scan.thread_exit) {
862 MMRADIO_LOG_DEBUG("exiting scan thread");
866 if (radio->scan.stop) {
867 MMRADIO_LOG_INFO("scan was canceled");
871 /* now we can get new frequency from radio device */
872 ret = radio_hal_get_frequency(radio->hal_inf, &freq);
873 if (ret != MM_ERROR_NONE) {
874 MMRADIO_LOG_ERROR("failed to get current frequency");
876 if (freq <= prev_freq) {
877 MMRADIO_LOG_ERROR("frequency is less than previous [%d] -> [%d] we wrapped around, we are finished scanning", prev_freq, freq);
881 prev_freq = param.radio_scan.frequency = (int)freq;
882 MMRADIO_LOG_INFO("scanning : new frequency : [%d]", param.radio_scan.frequency);
884 /* drop if max freq is scanned */
885 if (param.radio_scan.frequency >= radio->region_setting.band_max) {
886 MMRADIO_LOG_WARNING("%d freq is dropping...and stopping scan", param.radio_scan.frequency);
890 if (radio->scan.stop) {
891 /* doesn't need to post */
895 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_INFO, ¶m);
900 if (radio->old_state == MM_RADIO_STATE_READY) {
901 MMRADIO_LOG_DEBUG("old state is ready");
902 } else if (radio->old_state == MM_RADIO_STATE_PLAYING) {
903 MMRADIO_LOG_DEBUG("old state is playing");
904 ret = radio_hal_unmute(radio->hal_inf);
905 if (ret == MM_ERROR_NOT_SUPPORT_API) {
906 MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
907 } else if (ret != MM_ERROR_NONE) {
908 MMRADIO_LOG_ERROR("failed to set radio hal unmute");
911 ret = radio_hal_set_frequency(radio->hal_inf, prev_freq);
912 if (ret == MM_ERROR_NOT_SUPPORT_API) {
913 MMRADIO_LOG_WARNING("radio_hal_set_frequency is not supported");
914 } else if (ret != MM_ERROR_NONE) {
915 MMRADIO_LOG_ERROR("failed to set radio hal frequency");
921 if (radio->old_state == MM_RADIO_STATE_PLAYING) {
922 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_PLAYING);
924 /* close radio device here !!!! */
925 if (radio->is_ready) {
926 ret = radio_hal_close(radio->hal_inf);
927 if (ret == MM_ERROR_NOT_SUPPORT_API)
928 MMRADIO_LOG_WARNING("radio_hal_close is not supported");
929 else if (ret != MM_ERROR_NONE)
930 MMRADIO_LOG_ERROR("failed to close radio hal");
932 ret = radio_hal_unprepare(radio->hal_inf);
933 if (ret == MM_ERROR_NOT_SUPPORT_API)
934 MMRADIO_LOG_WARNING("radio_hal_unprepare is not supported");
935 else if (ret != MM_ERROR_NONE)
936 MMRADIO_LOG_ERROR("failed to unprepare radio hal");
938 if (!radio->interrupted_by_resource_conflict && /* is being released */
939 radio->radio_resource != NULL) {
940 ret = mm_resource_manager_mark_for_release(radio->resource_manager,
941 radio->radio_resource);
942 radio->radio_resource = NULL;
943 if (ret != MM_RESOURCE_MANAGER_ERROR_NONE)
944 MMRADIO_LOG_ERROR("failed to mark resource for release, ret(0x%x)", ret);
947 ret = mm_resource_manager_commit(radio->resource_manager);
948 if (ret != MM_RESOURCE_MANAGER_ERROR_NONE)
949 MMRADIO_LOG_ERROR("resource manager commit fail");
950 radio->is_ready = false;
952 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
955 if (!radio->scan.stop)
956 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_FINISH, NULL);
958 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_STOP, NULL);
960 radio->scan.is_running = false;
965 radio->scan.is_running = false;
967 MMRADIO_SCAN_THREAD_UNLOCK(radio);
969 MMRADIO_LOG_FLEAVE();
975 bool __is_tunable_frequency(mm_radio_t *radio, int freq)
977 MMRADIO_LOG_FENTER();
979 MMRADIO_CHECK_INSTANCE(radio);
981 if (freq >= radio->region_setting.band_max
982 || freq <= radio->region_setting.band_min)
985 MMRADIO_LOG_FLEAVE();
990 void __mmradio_seek_thread(mm_radio_t *radio)
992 int ret = MM_ERROR_NONE;
994 MMMessageParamType param = {0, };
996 MMRADIO_LOG_FENTER();
997 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
999 MMRADIO_SEEK_THREAD_LOCK(radio);
1001 while (!radio->seek.thread_exit) {
1002 MMRADIO_LOG_DEBUG("seek thread started. waiting for signal.");
1003 MMRADIO_SEEK_THREAD_WAIT(radio);
1005 if (radio->seek.thread_exit) {
1006 MMRADIO_LOG_DEBUG("exiting seek thread");
1010 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_START, NULL);
1011 MMRADIO_LOG_DEBUG("seeking....");
1013 if (radio->seek.stop) {
1014 MMRADIO_LOG_INFO("seek was canceled so we return failure to application");
1018 MMRADIO_LOG_DEBUG("try to seek ");
1019 MMRADIO_HAL_SEEK_THREAD_LOCK(radio);
1020 MMRADIO_LOG_DEBUG("seek start");
1021 ret = radio_hal_seek(radio->hal_inf, radio->seek_direction);
1022 MMRADIO_HAL_SEEK_THREAD_UNLOCK(radio);
1024 MMRADIO_LOG_ERROR("failed to seek radio hal");
1028 if (radio->seek.thread_exit) {
1029 MMRADIO_LOG_DEBUG("exiting seek thread");
1033 if (radio->seek.stop) {
1034 MMRADIO_LOG_INFO("seek was canceled so we return failure to application");
1038 /* now we can get new frequency from radio device */
1039 ret = radio_hal_get_frequency(radio->hal_inf, &freq);
1041 MMRADIO_LOG_ERROR("failed to get current frequency");
1045 MMRADIO_LOG_DEBUG("found frequency");
1047 /* if same freq is found, ignore it and search next one. */
1048 if (freq == radio->prev_seek_freq) {
1049 MMRADIO_LOG_WARNING("It's same with previous found one. So, trying next one.");
1053 /* check if it's limit freq or not */
1054 if (__is_tunable_frequency(radio, freq)) {
1055 /* now tune to new frequency */
1056 ret = radio_hal_set_frequency(radio->hal_inf, freq);
1058 MMRADIO_LOG_ERROR("failed to tune to new frequency");
1061 radio->freq = (int)freq;
1062 MMRADIO_LOG_WARNING("setting frequency : [%d]", radio->freq);
1065 if (radio->seek_unmute) {
1066 /* now turn on radio
1067 * In the case of limit freq, tuner should be unmuted.
1068 * Otherwise, sound can't output even though application set new frequency.
1070 ret = radio_hal_unmute(radio->hal_inf);
1072 MMRADIO_LOG_ERROR("failed to set unmute radio hal");
1075 radio->seek_unmute = false;
1078 param.radio_scan.frequency = radio->prev_seek_freq = (int)freq;
1079 MMRADIO_LOG_INFO("seeking : new frequency : [%d]", param.radio_scan.frequency);
1080 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, ¶m);
1081 radio->seek.is_running = false;
1085 if (radio->seek_unmute) {
1086 /* now turn on radio
1087 * In the case of limit freq, tuner should be unmuted.
1088 * Otherwise, sound can't output even though application set new frequency.
1090 ret = radio_hal_unmute(radio->hal_inf);
1092 MMRADIO_LOG_ERROR("failed to set unmute radio hal");
1093 radio->seek_unmute = false;
1095 /* freq -1 means it's failed to seek */
1096 param.radio_scan.frequency = -1;
1097 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, ¶m);
1098 radio->seek.is_running = false;
1102 radio->seek.is_running = false;
1103 MMRADIO_SEEK_THREAD_UNLOCK(radio);
1104 MMRADIO_LOG_FLEAVE();
1108 static bool __mmradio_post_message(mm_radio_t *radio, enum MMMessageType msgtype, MMMessageParamType *param)
1110 MMRADIO_CHECK_INSTANCE(radio);
1112 MMRADIO_LOG_FENTER();
1114 if (!radio->msg_cb) {
1115 MMRADIO_LOG_WARNING("failed to post a message because msg cb didn't register");
1119 MMRADIO_LOG_DEBUG("address of msg_cb : %p", radio->msg_cb);
1121 radio->msg_cb(msgtype, param, radio->msg_cb_param);
1123 MMRADIO_LOG_FLEAVE();
1128 static int __mmradio_check_state(mm_radio_t *radio, MMRadioCommand command)
1130 MMRadioStateType radio_state = MM_RADIO_STATE_NUM;
1132 MMRADIO_LOG_FENTER();
1134 MMRADIO_CHECK_INSTANCE(radio);
1136 radio_state = __mmradio_get_state(radio);
1138 MMRADIO_LOG_INFO("incomming command : %d current state : %d", command, radio_state);
1141 case MMRADIO_COMMAND_CREATE:
1143 if (radio_state != 0)
1148 case MMRADIO_COMMAND_REALIZE:
1150 if (radio_state == MM_RADIO_STATE_READY ||
1151 radio_state == MM_RADIO_STATE_PLAYING ||
1152 radio_state == MM_RADIO_STATE_SCANNING)
1155 if (radio_state == 0)
1160 case MMRADIO_COMMAND_UNREALIZE:
1162 if (radio_state == MM_RADIO_STATE_NULL)
1165 /* we can call unrealize at any higher state */
1169 case MMRADIO_COMMAND_START:
1171 if (radio_state == MM_RADIO_STATE_PLAYING)
1174 if (radio_state != MM_RADIO_STATE_READY)
1179 case MMRADIO_COMMAND_STOP:
1181 if (radio_state == MM_RADIO_STATE_READY)
1184 if (radio_state != MM_RADIO_STATE_PLAYING)
1189 case MMRADIO_COMMAND_START_SCAN:
1191 if (radio_state == MM_RADIO_STATE_SCANNING)
1194 if (radio_state == MM_RADIO_STATE_NULL)
1199 case MMRADIO_COMMAND_STOP_SCAN:
1201 if (radio_state == MM_RADIO_STATE_READY)
1204 if (radio_state != MM_RADIO_STATE_SCANNING)
1209 case MMRADIO_COMMAND_DESTROY:
1210 case MMRADIO_COMMAND_MUTE:
1211 case MMRADIO_COMMAND_UNMUTE:
1212 case MMRADIO_COMMAND_SET_FREQ:
1213 case MMRADIO_COMMAND_GET_FREQ:
1214 case MMRADIO_COMMAND_SET_REGION:
1215 case MMRADIO_COMMAND_SET_VOLUME:
1216 case MMRADIO_COMMAND_GET_VOLUME:
1218 /* we can do it at any state */
1222 case MMRADIO_COMMAND_SEEK:
1224 if (radio_state != MM_RADIO_STATE_PLAYING)
1229 case MMRADIO_COMMAND_GET_REGION:
1231 if (radio_state == MM_RADIO_STATE_NULL)
1237 MMRADIO_LOG_DEBUG("not handled in FSM. don't care it");
1241 MMRADIO_LOG_DEBUG("status OK");
1243 radio->cmd = command;
1245 MMRADIO_LOG_FLEAVE();
1247 return MM_ERROR_NONE;
1250 MMRADIO_LOG_WARNING("invalid state. current : %d command : %d", radio_state, command);
1251 MMRADIO_LOG_FLEAVE();
1252 return MM_ERROR_RADIO_INVALID_STATE;
1255 MMRADIO_LOG_WARNING("mm-radio is in the desired state(%d). doing noting", radio_state);
1256 MMRADIO_LOG_FLEAVE();
1257 return MM_ERROR_RADIO_NO_OP;
1261 static bool __mmradio_set_state(mm_radio_t *radio, int new_state)
1263 MMMessageParamType msg = { 0, };
1264 int msg_type = MM_MESSAGE_UNKNOWN;
1266 MMRADIO_LOG_FENTER();
1269 MMRADIO_LOG_WARNING("calling set_state with invalid radio handle");
1273 if (radio->current_state == new_state && radio->pending_state == 0) {
1274 MMRADIO_LOG_WARNING("we are in same state");
1279 radio->old_state = radio->current_state;
1280 radio->current_state = new_state;
1282 /* fill message param */
1283 msg.union_type = MM_MSG_UNION_STATE;
1284 msg.state.previous = radio->old_state;
1285 msg.state.current = radio->current_state;
1287 if (radio->interrupted_by_resource_conflict) {
1288 msg_type = MM_MESSAGE_STATE_INTERRUPTED;
1289 msg.state.code = MM_MSG_CODE_INTERRUPTED_BY_RESOURCE_CONFLICT;
1290 MMRADIO_POST_MSG(radio, msg_type, &msg);
1292 msg_type = MM_MESSAGE_STATE_CHANGED;
1293 MMRADIO_POST_MSG(radio, msg_type, &msg);
1296 MMRADIO_LOG_FLEAVE();
1301 static int __mmradio_get_state(mm_radio_t *radio)
1303 MMRADIO_CHECK_INSTANCE(radio);
1305 MMRADIO_LOG_INFO("radio state : current : [%d] old : [%d] pending : [%d]",
1306 radio->current_state, radio->old_state, radio->pending_state);
1308 return radio->current_state;
1311 static void __mmradio_volume_changed_cb(volume_type_t type, unsigned int volume, void *user_data)
1313 mm_radio_t *radio = (mm_radio_t *)user_data;
1314 int ret = MM_ERROR_NONE;
1315 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1316 if (type == VOLUME_TYPE_MEDIA) {
1317 MMRADIO_LOG_INFO("Change FM Radio volume to %d", volume);
1318 ret = __mmradio_set_media_volume(radio, volume);
1319 if (ret != MM_ERROR_NONE)
1320 MMRADIO_LOG_ERROR("failed to set media volume");
1325 int _mmradio_get_region_type(mm_radio_t *radio, MMRadioRegionType *type)
1327 MMRADIO_LOG_FENTER();
1328 MMRADIO_CHECK_INSTANCE(radio);
1329 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
1331 MMRADIO_RETURN_VAL_IF_FAIL(type, MM_ERROR_INVALID_ARGUMENT);
1333 *type = radio->region_setting.country;
1335 MMRADIO_LOG_FLEAVE();
1336 return MM_ERROR_NONE;
1339 int _mmradio_get_region_frequency_range(mm_radio_t *radio, unsigned int *min_freq, unsigned int *max_freq)
1341 MMRADIO_LOG_FENTER();
1342 MMRADIO_CHECK_INSTANCE(radio);
1343 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
1345 MMRADIO_RETURN_VAL_IF_FAIL(min_freq && max_freq, MM_ERROR_INVALID_ARGUMENT);
1347 *min_freq = radio->region_setting.band_min;
1348 *max_freq = radio->region_setting.band_max;
1350 MMRADIO_LOG_FLEAVE();
1351 return MM_ERROR_NONE;
1354 int _mmradio_get_channel_spacing(mm_radio_t *radio, unsigned int *ch_spacing)
1356 MMRADIO_LOG_FENTER();
1357 MMRADIO_CHECK_INSTANCE(radio);
1358 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
1360 MMRADIO_RETURN_VAL_IF_FAIL(ch_spacing, MM_ERROR_INVALID_ARGUMENT);
1362 *ch_spacing = radio->region_setting.channel_spacing;
1364 MMRADIO_LOG_FLEAVE();
1365 return MM_ERROR_NONE;
1368 int _mmradio_set_volume(mm_radio_t *radio, float volume)
1370 int ret = MM_ERROR_NONE;
1372 MMRADIO_LOG_FENTER();
1374 MMRADIO_CHECK_INSTANCE(radio);
1375 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_VOLUME);
1377 MMRADIO_LOG_INFO("Setting %f volume", volume);
1379 MMRADIO_VOLUME_LOCK(radio);
1380 radio->local_volume = volume;
1381 MMRADIO_VOLUME_UNLOCK(radio);
1383 ret = radio_hal_set_volume(radio->hal_inf, volume);
1384 if (ret != MM_ERROR_NONE)
1385 MMRADIO_LOG_ERROR("failed to set radio hal volume");
1387 MMRADIO_LOG_FLEAVE();
1392 int _mmradio_get_volume(mm_radio_t *radio, float *pVolume)
1394 int ret = MM_ERROR_NONE;
1396 MMRADIO_LOG_FENTER();
1398 MMRADIO_CHECK_INSTANCE(radio);
1399 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_VOLUME);
1401 MMRADIO_RETURN_VAL_IF_FAIL(pVolume, MM_ERROR_INVALID_ARGUMENT);
1403 ret = radio_hal_get_volume(radio->hal_inf, &volume);
1404 if (ret != MM_ERROR_NONE) {
1405 MMRADIO_LOG_ERROR("failed to get radio hal volume");
1410 MMRADIO_VOLUME_LOCK(radio);
1411 radio->local_volume = volume;
1412 *pVolume = (float)radio->local_volume;
1413 MMRADIO_VOLUME_UNLOCK(radio);
1415 MMRADIO_LOG_FLEAVE();
1420 static int __mmradio_set_media_volume(mm_radio_t *radio, unsigned int level)
1422 int ret = MM_ERROR_NONE;
1424 MMRADIO_LOG_FENTER();
1426 MMRADIO_CHECK_INSTANCE(radio);
1427 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_VOLUME);
1429 MMRADIO_LOG_INFO("Setting %d volume", level);
1431 MMRADIO_VOLUME_LOCK(radio);
1432 radio->media_volume = level;
1433 MMRADIO_VOLUME_UNLOCK(radio);
1435 ret = radio_hal_set_media_volume(radio->hal_inf, level);
1436 if (ret != MM_ERROR_NONE)
1437 MMRADIO_LOG_ERROR("failed to set radio hal media volume");
1439 MMRADIO_LOG_FLEAVE();
1444 static int __resource_release_cb(mm_resource_manager_h rm,
1445 mm_resource_manager_res_h res, void *user_data)
1447 mm_radio_t *radio = NULL;
1449 MMRADIO_LOG_FENTER();
1452 MMRADIO_LOG_ERROR("user_data is null");
1456 radio = (mm_radio_t *)user_data;
1457 radio->radio_resource = NULL;
1459 MMRADIO_LOG_DEBUG("radio resource conflict so, resource will be freed by _mmradio_stop");
1461 radio->interrupted_by_resource_conflict = TRUE;
1463 MMRADIO_CMD_LOCK(radio);
1464 if (_mmradio_stop(radio) != MM_ERROR_NONE)
1465 MMRADIO_LOG_ERROR("failed to stop radio");
1466 MMRADIO_CMD_UNLOCK(radio);
1468 MMRADIO_LOG_FLEAVE();
1473 static int __mmradio_create_thread(mm_radio_t *radio)
1475 int ret = MM_ERROR_NONE;
1477 MMRADIO_LOG_FENTER();
1479 MMRADIO_CHECK_INSTANCE(radio);
1481 MMRADIO_INIT_MUTEX(radio->cmd_lock);
1482 MMRADIO_INIT_MUTEX(radio->volume_lock);
1483 MMRADIO_INIT_MUTEX(radio->hal_seek_mutex);
1485 MMRADIO_INIT_MUTEX(radio->seek.mutex);
1486 MMRADIO_INIT_COND(radio->seek.cond);
1488 radio->seek.thread_id = pthread_create(&radio->seek.thread, NULL,
1489 (void *)__mmradio_seek_thread, (void *)radio);
1490 if (radio->seek.thread_id) {
1491 MMRADIO_LOG_DEBUG("failed to create thread : seek");
1495 MMRADIO_INIT_MUTEX(radio->scan.mutex);
1496 MMRADIO_INIT_COND(radio->scan.cond);
1498 radio->scan.thread_id = pthread_create(&radio->scan.thread, NULL,
1499 (void *)__mmradio_scan_thread, (void *)radio);
1500 if (radio->scan.thread_id) {
1501 MMRADIO_LOG_ERROR("failed to create thread : scan");
1505 MMRADIO_LOG_FLEAVE();
1510 if (radio->seek.thread) {
1511 MMRADIO_SEEK_THREAD_LOCK(radio);
1512 radio->seek.thread_exit = true;
1513 MMRADIO_SEEK_THREAD_SIGNAL(radio);
1514 MMRADIO_SEEK_THREAD_UNLOCK(radio);
1515 pthread_join(radio->seek.thread, NULL);
1516 radio->seek.thread = 0;
1519 pthread_mutex_destroy(&radio->cmd_lock);
1520 pthread_mutex_destroy(&radio->volume_lock);
1521 pthread_mutex_destroy(&radio->hal_seek_mutex);
1522 pthread_mutex_destroy(&radio->seek.mutex);
1523 pthread_cond_destroy(&radio->seek.cond);
1524 pthread_mutex_destroy(&radio->scan.mutex);
1525 pthread_cond_destroy(&radio->scan.cond);
1527 return MM_ERROR_RADIO_INTERNAL;
1530 static void __mmradio_destroy_thread(mm_radio_t *radio)
1532 MMRADIO_LOG_FENTER();
1534 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1536 if (radio->seek.thread) {
1537 MMRADIO_SEEK_THREAD_LOCK(radio);
1538 radio->seek.thread_exit = true;
1539 MMRADIO_SEEK_THREAD_SIGNAL(radio);
1540 MMRADIO_SEEK_THREAD_UNLOCK(radio);
1541 pthread_join(radio->seek.thread, NULL);
1542 radio->seek.thread = 0;
1545 if (radio->scan.thread) {
1546 MMRADIO_SCAN_THREAD_LOCK(radio);
1547 radio->scan.thread_exit = true;
1548 MMRADIO_SCAN_THREAD_SIGNAL(radio);
1549 MMRADIO_SCAN_THREAD_UNLOCK(radio);
1550 pthread_join(radio->scan.thread, NULL);
1551 radio->scan.thread = 0;
1554 pthread_mutex_destroy(&radio->cmd_lock);
1555 pthread_mutex_destroy(&radio->volume_lock);
1556 pthread_mutex_destroy(&radio->hal_seek_mutex);
1558 pthread_mutex_destroy(&radio->seek.mutex);
1559 pthread_cond_destroy(&radio->seek.cond);
1561 pthread_mutex_destroy(&radio->scan.mutex);
1562 pthread_cond_destroy(&radio->scan.cond);
1564 MMRADIO_LOG_FLEAVE();