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>
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")
48 * Internal Implementation
50 int _convert_error_code(int code, char *func_name)
52 int ret = RADIO_ERROR_NONE;
53 char* msg="RADIO_ERROR_NONE";
57 ret = RADIO_ERROR_NONE;
58 msg = "RADIO_ERROR_NONE";
61 case MM_ERROR_RADIO_NO_FREE_SPACE:
62 ret = RADIO_ERROR_OUT_OF_MEMORY;
63 msg = "RADIO_ERROR_OUT_OF_MEMORY";
65 case MM_ERROR_RADIO_NOT_INITIALIZED:
66 case MM_ERROR_RADIO_NO_OP:
67 ret = RADIO_ERROR_INVALID_STATE;
68 msg = "RADIO_ERROR_INVALID_STATE";
70 case MM_ERROR_COMMON_INVALID_ARGUMENT:
71 ret = RADIO_ERROR_INVALID_PARAMETER;
72 msg = "RADIO_ERROR_INVALID_PARAMETER";
74 case MM_ERROR_POLICY_BLOCKED:
75 case MM_ERROR_POLICY_INTERRUPTED:
76 case MM_ERROR_POLICY_INTERNAL:
77 case MM_ERROR_POLICY_DUPLICATED:
78 ret = RADIO_ERROR_SOUND_POLICY;
79 msg = "RADIO_ERROR_SOUND_POLICY";
81 case MM_ERROR_RADIO_INTERNAL:
82 case MM_ERROR_RADIO_RESPONSE_TIMEOUT:
83 case MM_ERROR_RADIO_DEVICE_NOT_OPENED:
84 case MM_ERROR_RADIO_DEVICE_NOT_FOUND:
86 ret= RADIO_ERROR_INVALID_OPERATION;
87 msg = "RADIO_ERROR_INVALID_OPERATION";
89 LOGE("[%s] %s(0x%08x) : core fw error(0x%x)",func_name,msg, ret, code);
93 radio_state_e _convert_radio_state(MMRadioStateType state)
95 int converted_state = RADIO_STATE_READY;
99 case MM_RADIO_STATE_PLAYING:
100 converted_state = RADIO_STATE_PLAYING;
102 case MM_RADIO_STATE_SCANNING:
103 converted_state = RADIO_STATE_SCANNING;
105 case MM_RADIO_STATE_NULL:
106 case MM_RADIO_STATE_READY:
108 converted_state = RADIO_STATE_READY;
111 return converted_state;
114 int _set_callback(_radio_event_e type, radio_h radio, void* callback, void *user_data)
116 RADIO_INSTANCE_CHECK(radio);
117 RADIO_NULL_ARG_CHECK(callback);
118 radio_s * handle = (radio_s *) radio;
119 handle->user_cb[type] = callback;
120 handle->user_data[type] = user_data;
121 LOGI("[%s] Event type : %d ",__FUNCTION__, type);
122 return RADIO_ERROR_NONE;
125 int _unset_callback(_radio_event_e type, radio_h radio)
127 RADIO_INSTANCE_CHECK(radio);
128 radio_s * handle = (radio_s *) radio;
129 handle->user_cb[type] = NULL;
130 handle->user_data[type] = NULL;
131 LOGI("[%s] Event type : %d ",__FUNCTION__, type);
132 return RADIO_ERROR_NONE;
135 int _msg_callback(int message, void *param, void *user_data)
137 radio_s * handle = (radio_s*)user_data;
138 MMMessageParamType *msg = (MMMessageParamType*)param;
139 LOGI("[%s] Got message type : 0x%x" ,__FUNCTION__, message);
142 case MM_MESSAGE_RADIO_SCAN_INFO:
143 if( handle->user_cb[_RADIO_EVENT_TYPE_SCAN_INFO] )
145 ((radio_scan_updated_cb)handle->user_cb[_RADIO_EVENT_TYPE_SCAN_INFO])(msg->radio_scan.frequency*100,handle->user_data[_RADIO_EVENT_TYPE_SCAN_INFO]);
148 case MM_MESSAGE_RADIO_SCAN_STOP:
149 if( handle->user_cb[_RADIO_EVENT_TYPE_SCAN_STOP] )
151 ((radio_scan_stopped_cb)handle->user_cb[_RADIO_EVENT_TYPE_SCAN_STOP])(handle->user_data[_RADIO_EVENT_TYPE_SCAN_STOP]);
154 case MM_MESSAGE_RADIO_SCAN_FINISH:
155 if( handle->user_cb[_RADIO_EVENT_TYPE_SCAN_FINISH] )
157 ((radio_scan_completed_cb)handle->user_cb[_RADIO_EVENT_TYPE_SCAN_FINISH])(handle->user_data[_RADIO_EVENT_TYPE_SCAN_FINISH]);
160 case MM_MESSAGE_RADIO_SEEK_FINISH:
161 if( handle->user_cb[_RADIO_EVENT_TYPE_SEEK_FINISH] )
163 ((radio_seek_completed_cb)handle->user_cb[_RADIO_EVENT_TYPE_SEEK_FINISH])(msg->radio_scan.frequency*100, handle->user_data[_RADIO_EVENT_TYPE_SEEK_FINISH]);
166 case MM_MESSAGE_STATE_INTERRUPTED:
167 if( handle->user_cb[_RADIO_EVENT_TYPE_INTERRUPT] )
169 ((radio_interrupted_cb)handle->user_cb[_RADIO_EVENT_TYPE_INTERRUPT])(msg->code,handle->user_data[_RADIO_EVENT_TYPE_INTERRUPT]);
172 case MM_MESSAGE_ERROR:
173 _convert_error_code(msg->code,(char*)__FUNCTION__);
175 case MM_MESSAGE_RADIO_SCAN_START:
176 LOGI("[%s] Scan Started");
178 case MM_MESSAGE_STATE_CHANGED:
179 handle->state = _convert_radio_state(msg->state.current);
180 LOGI("[%s] State Changed --- from : %d , to : %d" ,__FUNCTION__, _convert_radio_state(msg->state.previous), handle->state);
182 case MM_MESSAGE_RADIO_SEEK_START:
183 LOGI("[%s] Seek Started", __FUNCTION__);
193 * Public Implementation
195 int radio_create(radio_h *radio)
197 RADIO_INSTANCE_CHECK(radio);
199 handle = (radio_s*)malloc( sizeof(radio_s));
201 memset(handle, 0 , sizeof(radio_s));
204 LOGE("[%s] RADIO_ERROR_OUT_OF_MEMORY(0x%08x)" ,__FUNCTION__,RADIO_ERROR_OUT_OF_MEMORY);
205 return RADIO_ERROR_OUT_OF_MEMORY;
207 int ret = mm_radio_create(&handle->mm_handle);
208 if( ret != MM_ERROR_NONE)
210 LOGE("[%s] RADIO_ERROR_INVALID_OPERATION(0x%08x)" ,__FUNCTION__,RADIO_ERROR_INVALID_OPERATION);
213 return RADIO_ERROR_INVALID_OPERATION;
217 *radio = (radio_h)handle;
219 ret = mm_radio_set_message_callback(handle->mm_handle, _msg_callback, (void*)handle);
220 if(ret != MM_ERROR_NONE)
222 LOGW("[%s] Failed to set message callback function (0x%x)" ,__FUNCTION__, ret);
224 ret = mm_radio_realize(handle->mm_handle);
225 if(ret != MM_ERROR_NONE)
227 return _convert_error_code(ret,(char*)__FUNCTION__);
229 handle->state = RADIO_STATE_READY;
230 handle->mute = FALSE;
231 return RADIO_ERROR_NONE;
235 int radio_destroy(radio_h radio)
237 RADIO_INSTANCE_CHECK(radio);
238 radio_s * handle = (radio_s *) radio;
241 ret = mm_radio_unrealize(handle->mm_handle);
242 if ( ret!= MM_ERROR_NONE)
244 LOGW("[%s] Failed to unrealize (0x%x)" ,__FUNCTION__, ret);
247 ret = mm_radio_destroy(handle->mm_handle);
248 if (ret!= MM_ERROR_NONE)
250 LOGE("[%s] RADIO_ERROR_INVALID_OPERATION (0x%08x)" ,__FUNCTION__,RADIO_ERROR_INVALID_OPERATION);
251 return RADIO_ERROR_INVALID_OPERATION;
257 return RADIO_ERROR_NONE;
261 int radio_get_state(radio_h radio, radio_state_e *state)
263 RADIO_INSTANCE_CHECK(radio);
264 RADIO_NULL_ARG_CHECK(state);
265 radio_s * handle = (radio_s *) radio;
266 MMRadioStateType currentStat = MM_RADIO_STATE_NULL;
267 int ret = mm_radio_get_state(handle->mm_handle, ¤tStat);
268 if(ret != MM_ERROR_NONE)
270 *state = handle->state;
271 return _convert_error_code(ret,(char*)__FUNCTION__);
275 handle->state = _convert_radio_state(currentStat);
276 *state = handle->state;
277 return RADIO_ERROR_NONE;
281 int radio_start(radio_h radio)
283 RADIO_INSTANCE_CHECK(radio);
284 radio_s * handle = (radio_s *) radio;
285 RADIO_STATE_CHECK(handle,RADIO_STATE_READY);
287 int ret = mm_radio_start(handle->mm_handle);
288 if(ret != MM_ERROR_NONE)
290 return _convert_error_code(ret,(char*)__FUNCTION__);
294 handle->state = RADIO_STATE_PLAYING;
295 return RADIO_ERROR_NONE;
299 int radio_stop(radio_h radio)
301 RADIO_INSTANCE_CHECK(radio);
302 radio_s * handle = (radio_s *) radio;
303 RADIO_STATE_CHECK(handle,RADIO_STATE_PLAYING);
305 int ret = mm_radio_stop(handle->mm_handle);
306 if(ret != MM_ERROR_NONE)
308 return _convert_error_code(ret,(char*)__FUNCTION__);
312 handle->state = RADIO_STATE_READY;
313 return RADIO_ERROR_NONE;
317 int radio_seek_up(radio_h radio,radio_seek_completed_cb callback, void *user_data )
319 RADIO_INSTANCE_CHECK(radio);
320 radio_s * handle = (radio_s *) radio;
321 RADIO_STATE_CHECK(handle,RADIO_STATE_PLAYING);
325 _set_callback(_RADIO_EVENT_TYPE_SEEK_FINISH,radio,callback,user_data);
329 _unset_callback(_RADIO_EVENT_TYPE_SEEK_FINISH,radio);
332 int ret = mm_radio_seek(handle->mm_handle, MM_RADIO_SEEK_UP);
333 if(ret != MM_ERROR_NONE)
335 return _convert_error_code(ret,(char*)__FUNCTION__);
339 return RADIO_ERROR_NONE;
343 int radio_seek_down(radio_h radio,radio_seek_completed_cb callback, void *user_data )
345 RADIO_INSTANCE_CHECK(radio);
346 radio_s * handle = (radio_s *) radio;
347 RADIO_STATE_CHECK(handle,RADIO_STATE_PLAYING);
351 _set_callback(_RADIO_EVENT_TYPE_SEEK_FINISH,radio,callback,user_data);
355 _unset_callback(_RADIO_EVENT_TYPE_SEEK_FINISH,radio);
358 int ret = mm_radio_seek(handle->mm_handle, MM_RADIO_SEEK_DOWN);
359 if(ret != MM_ERROR_NONE)
361 return _convert_error_code(ret,(char*)__FUNCTION__);
365 return RADIO_ERROR_NONE;
369 int radio_set_frequency(radio_h radio, int frequency)
371 RADIO_INSTANCE_CHECK(radio);
372 if(frequency < 87500 || frequency > 108000)
374 LOGE("[%s] RADIO_ERROR_INVALID_PARAMETER(0x%08x) : Out of range (87500 ~ 108000)" ,__FUNCTION__,RADIO_ERROR_INVALID_PARAMETER);
375 return RADIO_ERROR_INVALID_PARAMETER;
377 int freq= frequency/100;
378 radio_s * handle = (radio_s *) radio;
379 int ret = mm_radio_set_frequency(handle->mm_handle, freq);
380 if(ret != MM_ERROR_NONE)
382 return _convert_error_code(ret,(char*)__FUNCTION__);
386 return RADIO_ERROR_NONE;
390 int radio_get_frequency(radio_h radio, int *frequency)
392 RADIO_INSTANCE_CHECK(radio);
393 radio_s * handle = (radio_s *) radio;
396 int ret = mm_radio_get_frequency(handle->mm_handle, &freq);
397 if(ret != MM_ERROR_NONE)
399 return _convert_error_code(ret,(char*)__FUNCTION__);
403 *frequency = freq*100;
404 return RADIO_ERROR_NONE;
408 int radio_scan_start(radio_h radio, radio_scan_updated_cb callback, void *user_data)
410 RADIO_INSTANCE_CHECK(radio);
411 radio_s * handle = (radio_s *) radio;
412 RADIO_STATE_CHECK(handle,RADIO_STATE_READY);
416 _set_callback(_RADIO_EVENT_TYPE_SCAN_INFO,radio,callback,user_data);
420 _unset_callback(_RADIO_EVENT_TYPE_SCAN_INFO,radio);
423 int ret = mm_radio_scan_start(handle->mm_handle);
424 if(ret != MM_ERROR_NONE)
426 return _convert_error_code(ret,(char*)__FUNCTION__);
430 handle->state = RADIO_STATE_SCANNING;
431 return RADIO_ERROR_NONE;
435 int radio_scan_stop(radio_h radio, radio_scan_stopped_cb callback, void *user_data)
437 RADIO_INSTANCE_CHECK(radio);
438 radio_s * handle = (radio_s *) radio;
439 RADIO_STATE_CHECK(handle,RADIO_STATE_SCANNING);
443 _set_callback(_RADIO_EVENT_TYPE_SCAN_STOP,radio,callback,user_data);
447 _unset_callback(_RADIO_EVENT_TYPE_SCAN_STOP,radio);
450 int ret = mm_radio_scan_stop(handle->mm_handle);
451 if(ret != MM_ERROR_NONE)
453 return _convert_error_code(ret,(char*)__FUNCTION__);
457 handle->state = RADIO_STATE_READY;
458 return RADIO_ERROR_NONE;
463 int radio_set_mute(radio_h radio, bool muted)
465 RADIO_INSTANCE_CHECK(radio);
466 radio_s * handle = (radio_s *) radio;
468 int ret = mm_radio_set_mute(handle->mm_handle, muted);
469 if(ret != MM_ERROR_NONE)
471 return _convert_error_code(ret,(char*)__FUNCTION__);
475 handle->mute = muted;
476 return RADIO_ERROR_NONE;
480 int radio_is_muted(radio_h radio, bool *muted)
482 RADIO_INSTANCE_CHECK(radio);
483 RADIO_NULL_ARG_CHECK(muted);
484 radio_s * handle = (radio_s *) radio;
485 *muted = handle->mute;
486 return RADIO_ERROR_NONE;
489 int radio_set_scan_completed_cb(radio_h radio, radio_scan_completed_cb callback, void *user_data)
491 return _set_callback(_RADIO_EVENT_TYPE_SCAN_FINISH,radio,callback,user_data);
494 int radio_unset_scan_completed_cb(radio_h radio)
496 return _unset_callback(_RADIO_EVENT_TYPE_SCAN_FINISH,radio);
499 int radio_set_interrupted_cb(radio_h radio, radio_interrupted_cb callback, void *user_data)
501 return _set_callback(_RADIO_EVENT_TYPE_INTERRUPT,radio,callback,user_data);
504 int radio_unset_interrupted_cb(radio_h radio)
506 return _unset_callback(_RADIO_EVENT_TYPE_INTERRUPT,radio);