2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
21 #include <radio_private.h>
24 #include <system_info.h>
29 #define LOG_TAG "TIZEN_N_RADIO"
34 #define RADIO_CHECK_CONDITION(condition,error,msg) \
35 if(condition) {} else \
36 { LOGE("[%s] %s(0x%08x)",(char*)__FUNCTION__, msg,error); return error;}; \
38 #define RADIO_INSTANCE_CHECK(radio) \
39 RADIO_CHECK_CONDITION(radio != NULL, RADIO_ERROR_INVALID_PARAMETER,"RADIO_ERROR_INVALID_PARAMETER")
41 #define RADIO_STATE_CHECK(radio,expected_state) \
42 RADIO_CHECK_CONDITION(radio->state == expected_state,RADIO_ERROR_INVALID_STATE,"RADIO_ERROR_INVALID_STATE")
44 #define RADIO_NULL_ARG_CHECK(arg) \
45 RADIO_CHECK_CONDITION(arg != NULL,RADIO_ERROR_INVALID_PARAMETER,"RADIO_ERROR_INVALID_PARAMETER")
47 #define RADIO_SUPPORT_CHECK(arg) \
48 RADIO_CHECK_CONDITION(arg != false, RADIO_ERROR_NOT_SUPPORTED,"RADIO_ERROR_NOT_SUPPORTED")
51 * Internal Implementation
53 static int __convert_error_code(int code, char *func_name)
55 int ret = RADIO_ERROR_NONE;
56 char* msg="RADIO_ERROR_NONE";
57 LOGI("[%s] Enter code :%x", __func__, code);
61 ret = RADIO_ERROR_NONE;
62 msg = "RADIO_ERROR_NONE";
65 case MM_ERROR_RADIO_NO_FREE_SPACE:
66 ret = RADIO_ERROR_OUT_OF_MEMORY;
67 msg = "RADIO_ERROR_OUT_OF_MEMORY";
69 case MM_ERROR_RADIO_NOT_INITIALIZED:
70 case MM_ERROR_RADIO_NO_OP:
71 case MM_ERROR_RADIO_INVALID_STATE:
72 ret = RADIO_ERROR_INVALID_STATE;
73 msg = "RADIO_ERROR_INVALID_STATE";
75 case MM_ERROR_COMMON_INVALID_ARGUMENT:
76 ret = RADIO_ERROR_INVALID_PARAMETER;
77 msg = "RADIO_ERROR_INVALID_PARAMETER";
79 case MM_ERROR_POLICY_BLOCKED:
80 case MM_ERROR_POLICY_INTERRUPTED:
81 case MM_ERROR_POLICY_INTERNAL:
82 case MM_ERROR_POLICY_DUPLICATED:
83 ret = RADIO_ERROR_SOUND_POLICY;
84 msg = "RADIO_ERROR_SOUND_POLICY";
86 case MM_ERROR_RADIO_INTERNAL:
87 case MM_ERROR_RADIO_RESPONSE_TIMEOUT:
88 ret= RADIO_ERROR_INVALID_OPERATION;
89 msg = "RADIO_ERROR_INVALID_OPERATION";
91 case MM_ERROR_RADIO_DEVICE_NOT_FOUND:
92 ret = RADIO_ERROR_NOT_SUPPORTED;
93 msg = "RADIO_ERROR_NOT_SUPPORTED";
95 case MM_ERROR_RADIO_DEVICE_NOT_OPENED:
97 ret= RADIO_ERROR_PERMISSION_DENIED;
98 msg = "RADIO_ERROR_PERMISSION_DENIED";
100 LOGE("[%s] %s(0x%08x) : core fw error(0x%x)",func_name,msg, ret, code);
104 static radio_state_e __convert_radio_state(MMRadioStateType state)
106 int converted_state = RADIO_STATE_READY;
107 LOGI("[%s] Enter state: %d", __func__, state);
111 case MM_RADIO_STATE_PLAYING:
112 converted_state = RADIO_STATE_PLAYING;
114 case MM_RADIO_STATE_SCANNING:
115 converted_state = RADIO_STATE_SCANNING;
117 case MM_RADIO_STATE_NULL:
118 case MM_RADIO_STATE_READY:
120 converted_state = RADIO_STATE_READY;
123 LOGI("[%s] Leave converted_state: %d", __func__, converted_state);
124 return converted_state;
128 static radio_interrupted_code_e __convert_interrupted_code(int code)
130 LOGI("[%s] Enter code: %d", __func__, code);
131 radio_interrupted_code_e ret = RADIO_INTERRUPTED_BY_RESOURCE_CONFLICT;
134 case MM_MSG_CODE_INTERRUPTED_BY_CALL_END:
135 case MM_MSG_CODE_INTERRUPTED_BY_ALARM_END:
136 case MM_MSG_CODE_INTERRUPTED_BY_EMERGENCY_END:
137 case MM_MSG_CODE_INTERRUPTED_BY_NOTIFICATION_END:
138 ret = RADIO_INTERRUPTED_COMPLETED;
140 case MM_MSG_CODE_INTERRUPTED_BY_MEDIA:
141 case MM_MSG_CODE_INTERRUPTED_BY_OTHER_PLAYER_APP:
142 ret = RADIO_INTERRUPTED_BY_MEDIA;
144 case MM_MSG_CODE_INTERRUPTED_BY_CALL_START:
145 ret = RADIO_INTERRUPTED_BY_CALL;
147 case MM_MSG_CODE_INTERRUPTED_BY_EARJACK_UNPLUG:
148 ret = RADIO_INTERRUPTED_BY_EARJACK_UNPLUG;
150 case MM_MSG_CODE_INTERRUPTED_BY_ALARM_START:
151 ret = RADIO_INTERRUPTED_BY_ALARM;
153 case MM_MSG_CODE_INTERRUPTED_BY_NOTIFICATION_START:
154 ret = RADIO_INTERRUPTED_BY_NOTIFICATION;
156 case MM_MSG_CODE_INTERRUPTED_BY_EMERGENCY_START:
157 ret = RADIO_INTERRUPTED_BY_EMERGENCY;
159 case MM_MSG_CODE_INTERRUPTED_BY_RESUMABLE_MEDIA:
160 ret = RADIO_INTERRUPTED_BY_RESUMABLE_MEDIA;
162 case MM_MSG_CODE_INTERRUPTED_BY_RESOURCE_CONFLICT:
164 ret = RADIO_INTERRUPTED_BY_RESOURCE_CONFLICT;
167 LOGE("[%s] interrupted code(%d) => ret(%d)",__FUNCTION__,code, ret);
171 static int __set_callback(_radio_event_e type, radio_h radio, void* callback, void *user_data)
173 RADIO_INSTANCE_CHECK(radio);
174 RADIO_NULL_ARG_CHECK(callback);
175 radio_s * handle = (radio_s *) radio;
176 handle->user_cb[type] = callback;
177 handle->user_data[type] = user_data;
178 LOGI("[%s] Event type : %d ",__FUNCTION__, type);
179 return RADIO_ERROR_NONE;
182 static int __unset_callback(_radio_event_e type, radio_h radio)
184 RADIO_INSTANCE_CHECK(radio);
185 radio_s * handle = (radio_s *) radio;
186 handle->user_cb[type] = NULL;
187 handle->user_data[type] = NULL;
188 LOGI("[%s] Event type : %d ",__FUNCTION__, type);
189 return RADIO_ERROR_NONE;
192 static int __msg_callback(int message, void *param, void *user_data)
194 radio_s * handle = (radio_s*)user_data;
195 MMMessageParamType *msg = (MMMessageParamType*)param;
196 LOGI("[%s] Got message type : 0x%x" ,__FUNCTION__, message);
199 case MM_MESSAGE_RADIO_SCAN_INFO:
200 if( handle->user_cb[_RADIO_EVENT_TYPE_SCAN_INFO] )
202 ((radio_scan_updated_cb)handle->user_cb[_RADIO_EVENT_TYPE_SCAN_INFO])(msg->radio_scan.frequency,handle->user_data[_RADIO_EVENT_TYPE_SCAN_INFO]);
205 case MM_MESSAGE_RADIO_SCAN_STOP:
206 if( handle->user_cb[_RADIO_EVENT_TYPE_SCAN_STOP] )
208 ((radio_scan_stopped_cb)handle->user_cb[_RADIO_EVENT_TYPE_SCAN_STOP])(handle->user_data[_RADIO_EVENT_TYPE_SCAN_STOP]);
211 case MM_MESSAGE_RADIO_SCAN_FINISH:
212 if( handle->user_cb[_RADIO_EVENT_TYPE_SCAN_FINISH] )
214 ((radio_scan_completed_cb)handle->user_cb[_RADIO_EVENT_TYPE_SCAN_FINISH])(handle->user_data[_RADIO_EVENT_TYPE_SCAN_FINISH]);
217 case MM_MESSAGE_RADIO_SEEK_FINISH:
218 if( handle->user_cb[_RADIO_EVENT_TYPE_SEEK_FINISH] )
220 ((radio_seek_completed_cb)handle->user_cb[_RADIO_EVENT_TYPE_SEEK_FINISH])(msg->radio_scan.frequency, handle->user_data[_RADIO_EVENT_TYPE_SEEK_FINISH]);
223 case MM_MESSAGE_STATE_INTERRUPTED:
224 if( handle->user_cb[_RADIO_EVENT_TYPE_INTERRUPT] )
226 ((radio_interrupted_cb)handle->user_cb[_RADIO_EVENT_TYPE_INTERRUPT])(__convert_interrupted_code(msg->code),handle->user_data[_RADIO_EVENT_TYPE_INTERRUPT]);
229 case MM_MESSAGE_READY_TO_RESUME:
230 if( handle->user_cb[_RADIO_EVENT_TYPE_INTERRUPT] )
232 ((radio_interrupted_cb)handle->user_cb[_RADIO_EVENT_TYPE_INTERRUPT])(RADIO_INTERRUPTED_COMPLETED,handle->user_data[_RADIO_EVENT_TYPE_INTERRUPT]);
235 case MM_MESSAGE_ERROR:
236 __convert_error_code(msg->code,(char*)__FUNCTION__);
238 case MM_MESSAGE_RADIO_SCAN_START:
239 LOGI("[%s] Scan Started");
241 case MM_MESSAGE_STATE_CHANGED:
242 handle->state = __convert_radio_state(msg->state.current);
243 LOGI("[%s] State Changed --- from : %d , to : %d" ,__FUNCTION__, __convert_radio_state(msg->state.previous), handle->state);
245 case MM_MESSAGE_RADIO_SEEK_START:
246 LOGI("[%s] Seek Started", __FUNCTION__);
254 static int __radio_check_system_info_feature_supported()
259 nRetVal = system_info_get_platform_bool("http://tizen.org/feature/fmradio", &bValue);
261 if ( nRetVal != SYSTEM_INFO_ERROR_NONE )
263 LOGE("[%s] SYSTEM_INFO_ERROR : ", __FUNCTION__);
267 if ( false == bValue )
269 LOGI("system_info_get_platform_bool returned Unsupported feature capability\n");
273 LOGI("system_info_get_platform_bool returned Supported status feature\n");
280 * Public Implementation
282 int radio_create(radio_h *radio)
284 LOGI("[%s] Enter", __func__);
285 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
286 RADIO_INSTANCE_CHECK(radio);
289 handle = (radio_s*)malloc( sizeof(radio_s));
291 memset(handle, 0 , sizeof(radio_s));
294 LOGE("[%s] RADIO_ERROR_OUT_OF_MEMORY(0x%08x)" ,__FUNCTION__,RADIO_ERROR_OUT_OF_MEMORY);
295 return RADIO_ERROR_OUT_OF_MEMORY;
297 int ret = mm_radio_create(&handle->mm_handle);
298 if( ret != MM_ERROR_NONE)
302 return __convert_error_code(ret,(char*)__FUNCTION__);
306 *radio = (radio_h)handle;
308 ret = mm_radio_set_message_callback(handle->mm_handle, __msg_callback, (void*)handle);
309 if(ret != MM_ERROR_NONE)
311 LOGW("[%s] Failed to set message callback function (0x%x)" ,__FUNCTION__, ret);
313 ret = mm_radio_realize(handle->mm_handle);
314 if(ret != MM_ERROR_NONE)
316 return __convert_error_code(ret,(char*)__FUNCTION__);
318 handle->state = RADIO_STATE_READY;
319 handle->mute = FALSE;
320 return RADIO_ERROR_NONE;
324 int radio_destroy(radio_h radio)
326 LOGI("[%s] Enter", __func__);
327 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
328 RADIO_INSTANCE_CHECK(radio);
329 radio_s * handle = (radio_s *) radio;
332 ret = mm_radio_unrealize(handle->mm_handle);
333 if ( ret!= MM_ERROR_NONE)
335 LOGW("[%s] Failed to unrealize (0x%x)" ,__FUNCTION__, ret);
338 ret = mm_radio_destroy(handle->mm_handle);
339 if (ret!= MM_ERROR_NONE)
341 return __convert_error_code(ret,(char*)__FUNCTION__);
347 return RADIO_ERROR_NONE;
351 int radio_get_state(radio_h radio, radio_state_e *state)
353 LOGI("[%s] Enter", __func__);
354 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
355 RADIO_INSTANCE_CHECK(radio);
356 RADIO_NULL_ARG_CHECK(state);
357 radio_s * handle = (radio_s *) radio;
358 MMRadioStateType currentStat = MM_RADIO_STATE_NULL;
359 int ret = mm_radio_get_state(handle->mm_handle, ¤tStat);
360 if(ret != MM_ERROR_NONE)
362 *state = handle->state;
363 return __convert_error_code(ret,(char*)__FUNCTION__);
367 handle->state = __convert_radio_state(currentStat);
368 *state = handle->state;
369 return RADIO_ERROR_NONE;
373 int radio_start(radio_h radio)
375 LOGI("[%s] Enter", __func__);
376 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
377 RADIO_INSTANCE_CHECK(radio);
378 radio_s * handle = (radio_s *) radio;
379 RADIO_STATE_CHECK(handle,RADIO_STATE_READY);
381 int ret = mm_radio_start(handle->mm_handle);
382 if(ret != MM_ERROR_NONE)
384 return __convert_error_code(ret,(char*)__FUNCTION__);
388 handle->state = RADIO_STATE_PLAYING;
389 return RADIO_ERROR_NONE;
393 int radio_stop(radio_h radio)
395 LOGI("[%s] Enter", __func__);
396 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
397 RADIO_INSTANCE_CHECK(radio);
398 radio_s * handle = (radio_s *) radio;
399 RADIO_STATE_CHECK(handle,RADIO_STATE_PLAYING);
401 int ret = mm_radio_stop(handle->mm_handle);
402 if(ret != MM_ERROR_NONE)
404 return __convert_error_code(ret,(char*)__FUNCTION__);
408 handle->state = RADIO_STATE_READY;
409 return RADIO_ERROR_NONE;
413 int radio_seek_up(radio_h radio,radio_seek_completed_cb callback, void *user_data )
415 LOGI("[%s] Enter", __func__);
416 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
417 RADIO_INSTANCE_CHECK(radio);
418 radio_s * handle = (radio_s *) radio;
419 RADIO_STATE_CHECK(handle,RADIO_STATE_PLAYING);
423 __set_callback(_RADIO_EVENT_TYPE_SEEK_FINISH,radio,callback,user_data);
427 __unset_callback(_RADIO_EVENT_TYPE_SEEK_FINISH,radio);
430 int ret = mm_radio_seek(handle->mm_handle, MM_RADIO_SEEK_UP);
431 if(ret != MM_ERROR_NONE)
433 return __convert_error_code(ret,(char*)__FUNCTION__);
437 return RADIO_ERROR_NONE;
441 int radio_seek_down(radio_h radio,radio_seek_completed_cb callback, void *user_data )
443 LOGI("[%s] Enter", __func__);
444 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
445 RADIO_INSTANCE_CHECK(radio);
446 radio_s * handle = (radio_s *) radio;
447 RADIO_STATE_CHECK(handle,RADIO_STATE_PLAYING);
451 __set_callback(_RADIO_EVENT_TYPE_SEEK_FINISH,radio,callback,user_data);
455 __unset_callback(_RADIO_EVENT_TYPE_SEEK_FINISH,radio);
458 int ret = mm_radio_seek(handle->mm_handle, MM_RADIO_SEEK_DOWN);
459 if(ret != MM_ERROR_NONE)
461 return __convert_error_code(ret,(char*)__FUNCTION__);
465 return RADIO_ERROR_NONE;
469 int radio_set_frequency(radio_h radio, int frequency)
471 LOGI("[%s] Enter", __func__);
472 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
473 RADIO_INSTANCE_CHECK(radio);
474 if(frequency < 87500 || frequency > 108000)
476 LOGE("[%s] RADIO_ERROR_INVALID_PARAMETER(0x%08x) : Out of range (87500 ~ 108000)" ,__FUNCTION__,RADIO_ERROR_INVALID_PARAMETER);
477 return RADIO_ERROR_INVALID_PARAMETER;
480 radio_s * handle = (radio_s *) radio;
481 int ret = mm_radio_set_frequency(handle->mm_handle, freq);
482 if(ret != MM_ERROR_NONE)
484 return __convert_error_code(ret,(char*)__FUNCTION__);
488 return RADIO_ERROR_NONE;
492 int radio_get_frequency(radio_h radio, int *frequency)
494 LOGI("[%s] Enter", __func__);
495 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
496 RADIO_INSTANCE_CHECK(radio);
497 RADIO_NULL_ARG_CHECK(frequency);
498 radio_s * handle = (radio_s *) radio;
501 int ret = mm_radio_get_frequency(handle->mm_handle, &freq);
502 if(ret != MM_ERROR_NONE)
504 return __convert_error_code(ret,(char*)__FUNCTION__);
509 return RADIO_ERROR_NONE;
513 int radio_get_signal_strength(radio_h radio, int *strength)
515 LOGI("[%s] Enter", __func__);
516 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
517 RADIO_INSTANCE_CHECK(radio);
518 RADIO_NULL_ARG_CHECK(strength);
519 radio_s * handle = (radio_s *) radio;
522 int ret = mm_radio_get_signal_strength(handle->mm_handle, &_strength);
523 if(ret != MM_ERROR_NONE)
525 return __convert_error_code(ret,(char*)__FUNCTION__);
529 *strength = _strength;
530 return RADIO_ERROR_NONE;
534 int radio_scan_start(radio_h radio, radio_scan_updated_cb callback, void *user_data)
536 LOGI("[%s] Enter", __func__);
537 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
538 RADIO_INSTANCE_CHECK(radio);
539 radio_s * handle = (radio_s *) radio;
540 RADIO_STATE_CHECK(handle,RADIO_STATE_READY);
544 __set_callback(_RADIO_EVENT_TYPE_SCAN_INFO,radio,callback,user_data);
548 __unset_callback(_RADIO_EVENT_TYPE_SCAN_INFO,radio);
551 int ret = mm_radio_scan_start(handle->mm_handle);
552 if(ret != MM_ERROR_NONE)
554 return __convert_error_code(ret,(char*)__FUNCTION__);
558 handle->state = RADIO_STATE_SCANNING;
559 return RADIO_ERROR_NONE;
563 int radio_scan_stop(radio_h radio, radio_scan_stopped_cb callback, void *user_data)
565 LOGI("[%s] Enter", __func__);
566 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
567 RADIO_INSTANCE_CHECK(radio);
568 radio_s * handle = (radio_s *) radio;
569 RADIO_STATE_CHECK(handle,RADIO_STATE_SCANNING);
573 __set_callback(_RADIO_EVENT_TYPE_SCAN_STOP,radio,callback,user_data);
577 __unset_callback(_RADIO_EVENT_TYPE_SCAN_STOP,radio);
580 int ret = mm_radio_scan_stop(handle->mm_handle);
581 if(ret != MM_ERROR_NONE)
583 return __convert_error_code(ret,(char*)__FUNCTION__);
587 handle->state = RADIO_STATE_READY;
588 return RADIO_ERROR_NONE;
593 int radio_set_mute(radio_h radio, bool muted)
595 LOGI("[%s] Enter", __func__);
596 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
597 RADIO_INSTANCE_CHECK(radio);
598 radio_s * handle = (radio_s *) radio;
600 int ret = mm_radio_set_mute(handle->mm_handle, muted);
601 if(ret != MM_ERROR_NONE)
603 return __convert_error_code(ret,(char*)__FUNCTION__);
607 handle->mute = muted;
608 return RADIO_ERROR_NONE;
612 int radio_is_muted(radio_h radio, bool *muted)
614 LOGI("[%s] Enter", __func__);
615 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
616 RADIO_INSTANCE_CHECK(radio);
617 RADIO_NULL_ARG_CHECK(muted);
618 radio_s * handle = (radio_s *) radio;
619 *muted = handle->mute;
620 return RADIO_ERROR_NONE;
623 int radio_set_scan_completed_cb(radio_h radio, radio_scan_completed_cb callback, void *user_data)
625 LOGI("[%s] Enter", __func__);
626 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
627 return __set_callback(_RADIO_EVENT_TYPE_SCAN_FINISH,radio,callback,user_data);
630 int radio_unset_scan_completed_cb(radio_h radio)
632 LOGI("[%s] Enter", __func__);
633 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
634 return __unset_callback(_RADIO_EVENT_TYPE_SCAN_FINISH,radio);
637 int radio_set_interrupted_cb(radio_h radio, radio_interrupted_cb callback, void *user_data)
639 LOGI("[%s] Enter", __func__);
640 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
641 return __set_callback(_RADIO_EVENT_TYPE_INTERRUPT,radio,callback,user_data);
644 int radio_unset_interrupted_cb(radio_h radio)
646 LOGI("[%s] Enter", __func__);
647 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
648 return __unset_callback(_RADIO_EVENT_TYPE_INTERRUPT,radio);