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>
22 #include <system_info.h>
25 * Internal Implementation
27 static int __convert_error_code(int code, char *func_name)
29 int ret = RADIO_ERROR_NONE;
30 char *msg = "RADIO_ERROR_NONE";
31 LOGI("Enter code :%x", code);
34 ret = RADIO_ERROR_NONE;
35 msg = "RADIO_ERROR_NONE";
37 case MM_ERROR_RADIO_NO_FREE_SPACE:
38 case MM_ERROR_OUT_OF_MEMORY:
39 ret = RADIO_ERROR_OUT_OF_MEMORY;
40 msg = "RADIO_ERROR_OUT_OF_MEMORY";
42 case MM_ERROR_RADIO_NOT_INITIALIZED:
43 case MM_ERROR_RADIO_NO_OP:
44 case MM_ERROR_RADIO_INVALID_STATE:
45 ret = RADIO_ERROR_INVALID_STATE;
46 msg = "RADIO_ERROR_INVALID_STATE";
48 case MM_ERROR_COMMON_INVALID_ARGUMENT:
49 case MM_ERROR_INVALID_ARGUMENT:
50 ret = RADIO_ERROR_INVALID_PARAMETER;
51 msg = "RADIO_ERROR_INVALID_PARAMETER";
53 case MM_ERROR_POLICY_BLOCKED:
54 case MM_ERROR_POLICY_INTERRUPTED:
55 case MM_ERROR_POLICY_INTERNAL:
56 case MM_ERROR_POLICY_DUPLICATED:
57 ret = RADIO_ERROR_SOUND_POLICY;
58 msg = "RADIO_ERROR_SOUND_POLICY";
60 case MM_ERROR_RADIO_DEVICE_NOT_FOUND:
61 ret = RADIO_ERROR_NOT_SUPPORTED;
62 msg = "RADIO_ERROR_NOT_SUPPORTED";
64 case MM_ERROR_RADIO_NO_ANTENNA:
65 ret = RADIO_ERROR_NO_ANTENNA;
66 msg = "RADIO_ERROR_NO_ANTENNA";
68 case MM_ERROR_RADIO_DEVICE_NOT_OPENED:
69 case MM_ERROR_RADIO_PERMISSION_DENIED:
70 ret = RADIO_ERROR_PERMISSION_DENIED;
71 msg = "RADIO_ERROR_PERMISSION_DENIED";
73 case MM_ERROR_NOT_IMPLEMENTED:
74 case MM_ERROR_RADIO_INTERNAL:
75 case MM_ERROR_RADIO_RESPONSE_TIMEOUT:
77 ret = RADIO_ERROR_INVALID_OPERATION;
78 msg = "RADIO_ERROR_INVALID_OPERATION";
81 LOGE("[%s] %s(0x%08x) : core fw error(0x%x)", func_name, msg, ret, code);
85 static radio_state_e __convert_radio_state(MMRadioStateType state)
87 int converted_state = RADIO_STATE_READY;
88 LOGI("Enter state: %d", state);
91 case MM_RADIO_STATE_PLAYING:
92 converted_state = RADIO_STATE_PLAYING;
94 case MM_RADIO_STATE_SCANNING:
95 converted_state = RADIO_STATE_SCANNING;
97 case MM_RADIO_STATE_NULL:
98 case MM_RADIO_STATE_READY:
100 converted_state = RADIO_STATE_READY;
103 LOGI("Leave converted_state: %d", converted_state);
104 return converted_state;
107 static int __set_callback(_radio_event_e type, radio_h radio, void *callback, void *user_data)
109 RADIO_INSTANCE_CHECK(radio);
110 RADIO_NULL_ARG_CHECK(callback);
111 radio_s *handle = (radio_s *)radio;
112 handle->user_cb[type] = callback;
113 handle->user_data[type] = user_data;
114 LOGI("Event type : %d", type);
115 return RADIO_ERROR_NONE;
118 static int __unset_callback(_radio_event_e type, radio_h radio)
120 RADIO_INSTANCE_CHECK(radio);
121 radio_s *handle = (radio_s *)radio;
122 handle->user_cb[type] = NULL;
123 handle->user_data[type] = NULL;
124 LOGI("Event type : %d", type);
125 return RADIO_ERROR_NONE;
128 static int __msg_callback(int message, void *param, void *user_data)
130 radio_s *handle = (radio_s *)user_data;
131 MMMessageParamType *msg = (MMMessageParamType *)param;
132 LOGI("Got message type : 0x%x", message);
134 case MM_MESSAGE_RADIO_SCAN_INFO:
135 if (handle->user_cb[_RADIO_EVENT_TYPE_SCAN_INFO])
136 ((radio_scan_updated_cb)handle->user_cb[_RADIO_EVENT_TYPE_SCAN_INFO])(msg->radio_scan.frequency, handle->user_data[_RADIO_EVENT_TYPE_SCAN_INFO]);
138 case MM_MESSAGE_RADIO_SCAN_STOP:
139 if (handle->user_cb[_RADIO_EVENT_TYPE_SCAN_STOP])
140 ((radio_scan_stopped_cb)handle->user_cb[_RADIO_EVENT_TYPE_SCAN_STOP])(handle->user_data[_RADIO_EVENT_TYPE_SCAN_STOP]);
141 __unset_callback(_RADIO_EVENT_TYPE_SCAN_STOP, (radio_h)handle);
142 __unset_callback(_RADIO_EVENT_TYPE_SCAN_INFO, (radio_h)handle);
144 case MM_MESSAGE_RADIO_SCAN_FINISH:
145 if (handle->user_cb[_RADIO_EVENT_TYPE_SCAN_FINISH])
146 ((radio_scan_completed_cb)handle->user_cb[_RADIO_EVENT_TYPE_SCAN_FINISH])(handle->user_data[_RADIO_EVENT_TYPE_SCAN_FINISH]);
147 __unset_callback(_RADIO_EVENT_TYPE_SCAN_INFO, (radio_h)handle);
149 case MM_MESSAGE_RADIO_SEEK_FINISH:
150 if (handle->user_cb[_RADIO_EVENT_TYPE_SEEK_FINISH]) {
151 ((radio_seek_completed_cb)handle->user_cb[_RADIO_EVENT_TYPE_SEEK_FINISH])(msg->radio_scan.frequency, handle->user_data[_RADIO_EVENT_TYPE_SEEK_FINISH]);
152 handle->seeking = false;
154 __unset_callback(_RADIO_EVENT_TYPE_SEEK_FINISH, (radio_h)handle);
157 case MM_MESSAGE_STATE_INTERRUPTED:
158 if (msg->union_type == MM_MSG_UNION_STATE) {
159 handle->state = __convert_radio_state(msg->state.current);
160 if (handle->user_cb[_RADIO_EVENT_TYPE_INTERRUPT])
161 ((radio_interrupted_cb)handle->user_cb[_RADIO_EVENT_TYPE_INTERRUPT])(RADIO_INTERRUPTED_BY_RESOURCE_CONFLICT, handle->user_data[_RADIO_EVENT_TYPE_INTERRUPT]);
164 case MM_MESSAGE_ERROR:
165 __convert_error_code(msg->code, (char *)__FUNCTION__);
168 case MM_MESSAGE_RADIO_SCAN_START:
169 LOGI("Scan Started");
171 case MM_MESSAGE_STATE_CHANGED:
172 handle->state = __convert_radio_state(msg->state.current);
173 LOGI("State Changed --- from : %d , to : %d", __convert_radio_state(msg->state.previous), handle->state);
175 case MM_MESSAGE_RADIO_SEEK_START:
176 LOGI("Seek Started");
184 static int __radio_check_system_info_feature_supported()
189 ret = system_info_get_platform_bool("http://tizen.org/feature/fmradio", &val);
191 if (ret != SYSTEM_INFO_ERROR_NONE) {
192 LOGE("SYSTEM_INFO_ERROR");
197 LOGI("system_info_get_platform_bool returned Unsupported feature capability");
199 LOGI("system_info_get_platform_bool returned Supported status feature");
205 * Public Implementation
207 int radio_create(radio_h *radio)
210 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
211 RADIO_INSTANCE_CHECK(radio);
214 handle = (radio_s *)malloc(sizeof(radio_s));
216 LOGE("RADIO_ERROR_OUT_OF_MEMORY(0x%08x)", RADIO_ERROR_OUT_OF_MEMORY);
217 return RADIO_ERROR_OUT_OF_MEMORY;
220 memset(handle, 0, sizeof(radio_s));
222 int ret = mm_radio_create(&handle->mm_handle);
223 if (ret != MM_ERROR_NONE) {
226 return __convert_error_code(ret, (char *)__FUNCTION__);
229 *radio = (radio_h)handle;
231 ret = mm_radio_set_message_callback(handle->mm_handle, __msg_callback, (void *)handle);
232 if (ret != MM_ERROR_NONE)
233 LOGW("Failed to set message callback function (0x%x)", ret);
235 ret = mm_radio_realize(handle->mm_handle);
236 if (ret != MM_ERROR_NONE)
237 return __convert_error_code(ret, (char *)__FUNCTION__);
239 handle->state = RADIO_STATE_READY;
240 handle->mute = false;
241 handle->seeking = false;
242 return RADIO_ERROR_NONE;
245 int radio_destroy(radio_h radio)
248 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
249 RADIO_INSTANCE_CHECK(radio);
250 radio_s *handle = (radio_s *)radio;
253 ret = mm_radio_unrealize(handle->mm_handle);
254 if (ret != MM_ERROR_NONE)
255 LOGW("Failed to unrealize (0x%x)", ret);
257 ret = mm_radio_destroy(handle->mm_handle);
258 if (ret != MM_ERROR_NONE)
259 return __convert_error_code(ret, (char *)__FUNCTION__);
263 return RADIO_ERROR_NONE;
266 int radio_get_state(radio_h radio, radio_state_e *state)
269 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
270 RADIO_INSTANCE_CHECK(radio);
271 RADIO_NULL_ARG_CHECK(state);
272 radio_s *handle = (radio_s *)radio;
273 MMRadioStateType currentStat = MM_RADIO_STATE_NULL;
274 int ret = mm_radio_get_state(handle->mm_handle, ¤tStat);
275 if (ret != MM_ERROR_NONE) {
276 *state = handle->state;
277 return __convert_error_code(ret, (char *)__FUNCTION__);
280 handle->state = __convert_radio_state(currentStat);
281 *state = handle->state;
282 return RADIO_ERROR_NONE;
285 int radio_start(radio_h radio)
288 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
289 RADIO_INSTANCE_CHECK(radio);
290 radio_s *handle = (radio_s *)radio;
291 RADIO_STATE_CHECK(handle, RADIO_STATE_READY);
293 int ret = mm_radio_start(handle->mm_handle);
294 if (ret != MM_ERROR_NONE)
295 return __convert_error_code(ret, (char *)__FUNCTION__);
297 handle->state = RADIO_STATE_PLAYING;
298 return RADIO_ERROR_NONE;
301 int radio_stop(radio_h radio)
304 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
305 RADIO_INSTANCE_CHECK(radio);
306 radio_s *handle = (radio_s *)radio;
307 RADIO_STATE_CHECK(handle, RADIO_STATE_PLAYING);
309 int ret = mm_radio_stop(handle->mm_handle);
310 if (ret != MM_ERROR_NONE)
311 return __convert_error_code(ret, (char *)__FUNCTION__);
313 handle->state = RADIO_STATE_READY;
314 return RADIO_ERROR_NONE;
317 int radio_seek_up(radio_h radio, radio_seek_completed_cb callback, void *user_data)
320 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
321 RADIO_INSTANCE_CHECK(radio);
322 radio_s *handle = (radio_s *)radio;
323 RADIO_STATE_CHECK(handle, RADIO_STATE_PLAYING);
325 if (handle->seeking) {
326 LOGI("radio is seeking, can't serve another request try again");
327 return RADIO_ERROR_INVALID_OPERATION;
330 handle->seeking = true;
332 if (callback != NULL)
333 __set_callback(_RADIO_EVENT_TYPE_SEEK_FINISH, radio, callback, user_data);
335 __unset_callback(_RADIO_EVENT_TYPE_SEEK_FINISH, radio);
337 int ret = mm_radio_seek(handle->mm_handle, MM_RADIO_SEEK_UP);
338 if (ret != MM_ERROR_NONE)
339 return __convert_error_code(ret, (char *)__FUNCTION__);
341 return RADIO_ERROR_NONE;
344 int radio_seek_down(radio_h radio, radio_seek_completed_cb callback, void *user_data)
347 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
348 RADIO_INSTANCE_CHECK(radio);
349 radio_s *handle = (radio_s *)radio;
350 RADIO_STATE_CHECK(handle, RADIO_STATE_PLAYING);
352 if (handle->seeking) {
353 LOGI("radio is seeking, can't serve another request try again");
354 return RADIO_ERROR_INVALID_OPERATION;
357 handle->seeking = true;
359 if (callback != NULL)
360 __set_callback(_RADIO_EVENT_TYPE_SEEK_FINISH, radio, callback, user_data);
362 __unset_callback(_RADIO_EVENT_TYPE_SEEK_FINISH, radio);
364 int ret = mm_radio_seek(handle->mm_handle, MM_RADIO_SEEK_DOWN);
365 if (ret != MM_ERROR_NONE)
366 return __convert_error_code(ret, (char *)__FUNCTION__);
368 return RADIO_ERROR_NONE;
371 int radio_set_frequency(radio_h radio, int frequency)
374 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
375 RADIO_INSTANCE_CHECK(radio);
376 if (frequency < 87500 || frequency > 108000) {
377 LOGE("RADIO_ERROR_INVALID_PARAMETER(0x%08x) : Out of range (87500 ~ 108000)", RADIO_ERROR_INVALID_PARAMETER);
378 return RADIO_ERROR_INVALID_PARAMETER;
381 radio_s *handle = (radio_s *)radio;
382 int ret = mm_radio_set_frequency(handle->mm_handle, frequency);
383 if (ret != MM_ERROR_NONE)
384 return __convert_error_code(ret, (char *)__FUNCTION__);
386 return RADIO_ERROR_NONE;
389 int radio_get_frequency(radio_h radio, int *frequency)
392 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
393 RADIO_INSTANCE_CHECK(radio);
394 RADIO_NULL_ARG_CHECK(frequency);
395 radio_s *handle = (radio_s *)radio;
398 int ret = mm_radio_get_frequency(handle->mm_handle, &freq);
399 if (ret != MM_ERROR_NONE)
400 return __convert_error_code(ret, (char *)__FUNCTION__);
403 return RADIO_ERROR_NONE;
406 int radio_get_signal_strength(radio_h radio, int *strength)
409 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
410 RADIO_INSTANCE_CHECK(radio);
411 RADIO_NULL_ARG_CHECK(strength);
412 radio_s *handle = (radio_s *)radio;
415 int ret = mm_radio_get_signal_strength(handle->mm_handle, &_strength);
416 if (ret != MM_ERROR_NONE)
417 return __convert_error_code(ret, (char *)__FUNCTION__);
419 *strength = _strength;
420 return RADIO_ERROR_NONE;
423 int radio_scan_start(radio_h radio, radio_scan_updated_cb callback, void *user_data)
426 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
427 RADIO_INSTANCE_CHECK(radio);
428 radio_s *handle = (radio_s *)radio;
430 if (callback != NULL)
431 __set_callback(_RADIO_EVENT_TYPE_SCAN_INFO, radio, callback, user_data);
433 __unset_callback(_RADIO_EVENT_TYPE_SCAN_INFO, radio);
435 int ret = mm_radio_scan_start(handle->mm_handle);
436 if (ret != MM_ERROR_NONE)
437 return __convert_error_code(ret, (char *)__FUNCTION__);
439 handle->state = RADIO_STATE_SCANNING;
440 return RADIO_ERROR_NONE;
444 int radio_scan_stop(radio_h radio, radio_scan_stopped_cb callback, void *user_data)
447 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
448 RADIO_INSTANCE_CHECK(radio);
449 radio_s *handle = (radio_s *)radio;
450 RADIO_STATE_CHECK(handle, RADIO_STATE_SCANNING);
452 if (handle->user_cb[_RADIO_EVENT_TYPE_SCAN_STOP]) {
453 LOGW("Failed to stop scan (0x%x)", RADIO_ERROR_INVALID_OPERATION);
454 return RADIO_ERROR_INVALID_OPERATION;
457 if (callback != NULL)
458 __set_callback(_RADIO_EVENT_TYPE_SCAN_STOP, radio, callback, user_data);
460 __unset_callback(_RADIO_EVENT_TYPE_SCAN_STOP, radio);
462 int ret = mm_radio_scan_stop(handle->mm_handle);
463 if (ret != MM_ERROR_NONE)
464 return __convert_error_code(ret, (char *)__FUNCTION__);
466 return RADIO_ERROR_NONE;
469 int radio_set_mute(radio_h radio, bool muted)
472 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
473 RADIO_INSTANCE_CHECK(radio);
474 radio_s *handle = (radio_s *)radio;
476 int ret = mm_radio_set_mute(handle->mm_handle, muted);
477 if (ret != MM_ERROR_NONE)
478 return __convert_error_code(ret, (char *)__FUNCTION__);
480 handle->mute = muted;
481 return RADIO_ERROR_NONE;
485 int radio_is_muted(radio_h radio, bool *muted)
488 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
489 RADIO_INSTANCE_CHECK(radio);
490 RADIO_NULL_ARG_CHECK(muted);
491 radio_s *handle = (radio_s *)radio;
492 *muted = handle->mute;
493 return RADIO_ERROR_NONE;
496 int radio_set_scan_completed_cb(radio_h radio, radio_scan_completed_cb callback, void *user_data)
499 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
500 return __set_callback(_RADIO_EVENT_TYPE_SCAN_FINISH, radio, callback, user_data);
503 int radio_unset_scan_completed_cb(radio_h radio)
506 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
507 return __unset_callback(_RADIO_EVENT_TYPE_SCAN_FINISH, radio);
510 int radio_set_interrupted_cb(radio_h radio, radio_interrupted_cb callback, void *user_data)
513 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
514 return __set_callback(_RADIO_EVENT_TYPE_INTERRUPT, radio, callback, user_data);
517 int radio_unset_interrupted_cb(radio_h radio)
520 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
521 return __unset_callback(_RADIO_EVENT_TYPE_INTERRUPT, radio);
524 int radio_get_frequency_range(radio_h radio, int *min_freq, int *max_freq)
527 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
528 RADIO_INSTANCE_CHECK(radio);
529 RADIO_NULL_ARG_CHECK(min_freq);
530 RADIO_NULL_ARG_CHECK(max_freq);
531 radio_s *handle = (radio_s *)radio;
533 unsigned int min = 0;
534 unsigned int max = 0;
536 int ret = mm_radio_get_region_frequency_range(handle->mm_handle, &min, &max);
537 if (ret != MM_ERROR_NONE)
538 return __convert_error_code(ret, (char *)__FUNCTION__);
542 return RADIO_ERROR_NONE;
545 int radio_get_channel_spacing(radio_h radio, int *channel_spacing)
548 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
549 RADIO_INSTANCE_CHECK(radio);
551 radio_s *handle = (radio_s *)radio;
553 int ret = mm_radio_get_channel_spacing(handle->mm_handle, channel_spacing);
554 if (ret != MM_ERROR_NONE)
555 return __convert_error_code(ret, (char *)__FUNCTION__);
557 return RADIO_ERROR_NONE;
560 int radio_set_volume(radio_h radio, float volume)
563 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
564 RADIO_INSTANCE_CHECK(radio);
565 if (volume < 0.0 || volume > 1.0) {
566 LOGE("RADIO_ERROR_INVALID_PARAMETER(0x%08x) : Out of range (0.0 ~ 1.0)", RADIO_ERROR_INVALID_PARAMETER);
567 return RADIO_ERROR_INVALID_PARAMETER;
570 radio_s *handle = (radio_s *)radio;
571 int ret = mm_radio_set_volume(handle->mm_handle, volume);
572 if (ret != MM_ERROR_NONE)
573 return __convert_error_code(ret, (char *)__FUNCTION__);
575 return RADIO_ERROR_NONE;
578 int radio_get_volume(radio_h radio, float *volume)
581 RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
582 RADIO_INSTANCE_CHECK(radio);
583 RADIO_NULL_ARG_CHECK(volume);
584 radio_s *handle = (radio_s *)radio;
587 int ret = mm_radio_get_volume(handle->mm_handle, &vol);
588 if (ret != MM_ERROR_NONE)
589 return __convert_error_code(ret, (char *)__FUNCTION__);
592 return RADIO_ERROR_NONE;