9433e1f38e77113b510d6eca155fd4b020aa7eb3
[platform/core/api/radio.git] / src / radio.c
1 /*
2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <mm_types.h>
21 #include <radio_private.h>
22 #include <dlog.h>
23 #include <glib.h>
24 #include <system_info.h>
25
26 #ifdef LOG_TAG
27 #undef LOG_TAG
28 #endif
29 #define LOG_TAG "TIZEN_N_RADIO"
30
31 /*
32 * Internal Macros
33 */
34 #define RADIO_CHECK_CONDITION(condition, error, msg)    \
35         do {    \
36                 if (condition) { \
37                 } else {        \
38                         LOGE("[%s] %s(0x%08x)", (char *)__FUNCTION__, msg, error); \
39                         return error;   \
40                 } \
41         } while (0)
42
43 #define RADIO_INSTANCE_CHECK(radio)     \
44         RADIO_CHECK_CONDITION(radio != NULL, RADIO_ERROR_INVALID_PARAMETER, "RADIO_ERROR_INVALID_PARAMETER")
45
46 #define RADIO_STATE_CHECK(radio, expected_state)        \
47         RADIO_CHECK_CONDITION(radio->state == expected_state, RADIO_ERROR_INVALID_STATE, "RADIO_ERROR_INVALID_STATE")
48
49 #define RADIO_NULL_ARG_CHECK(arg)       \
50         RADIO_CHECK_CONDITION(arg != NULL, RADIO_ERROR_INVALID_PARAMETER, "RADIO_ERROR_INVALID_PARAMETER")
51
52 #define RADIO_SUPPORT_CHECK(arg)        \
53         RADIO_CHECK_CONDITION(arg != false, RADIO_ERROR_NOT_SUPPORTED, "RADIO_ERROR_NOT_SUPPORTED")
54
55 /*
56 * Internal Implementation
57 */
58 static int __convert_error_code(int code, char *func_name)
59 {
60         int ret = RADIO_ERROR_NONE;
61         char *msg = "RADIO_ERROR_NONE";
62         LOGI("[%s] Enter code :%x", __func__, code);
63         switch (code) {
64         case MM_ERROR_NONE:
65                 ret = RADIO_ERROR_NONE;
66                 msg = "RADIO_ERROR_NONE";
67                 break;
68
69         case MM_ERROR_RADIO_NO_FREE_SPACE:
70                 ret = RADIO_ERROR_OUT_OF_MEMORY;
71                 msg = "RADIO_ERROR_OUT_OF_MEMORY";
72                 break;
73         case MM_ERROR_RADIO_NOT_INITIALIZED:
74         case MM_ERROR_RADIO_NO_OP:
75         case MM_ERROR_RADIO_INVALID_STATE:
76                 ret = RADIO_ERROR_INVALID_STATE;
77                 msg = "RADIO_ERROR_INVALID_STATE";
78                 break;
79         case MM_ERROR_COMMON_INVALID_ARGUMENT:
80         case MM_ERROR_INVALID_ARGUMENT:
81                 ret = RADIO_ERROR_INVALID_PARAMETER;
82                 msg = "RADIO_ERROR_INVALID_PARAMETER";
83                 break;
84         case MM_ERROR_POLICY_BLOCKED:
85         case MM_ERROR_POLICY_INTERRUPTED:
86         case MM_ERROR_POLICY_INTERNAL:
87         case MM_ERROR_POLICY_DUPLICATED:
88                 ret = RADIO_ERROR_SOUND_POLICY;
89                 msg = "RADIO_ERROR_SOUND_POLICY";
90                 break;
91         case MM_ERROR_RADIO_INTERNAL:
92         case MM_ERROR_RADIO_RESPONSE_TIMEOUT:
93                 ret = RADIO_ERROR_INVALID_OPERATION;
94                 msg = "RADIO_ERROR_INVALID_OPERATION";
95                 break;
96         case MM_ERROR_RADIO_DEVICE_NOT_FOUND:
97                 ret = RADIO_ERROR_NOT_SUPPORTED;
98                 msg = "RADIO_ERROR_NOT_SUPPORTED";
99                 break;
100         case MM_ERROR_RADIO_NO_ANTENNA:
101                 ret = RADIO_ERROR_NO_ANTENNA;
102                 msg = "RADIO_ERROR_NO_ANTENNA";
103                 break;
104         case MM_ERROR_RADIO_DEVICE_NOT_OPENED:
105         default:
106                 ret = RADIO_ERROR_PERMISSION_DENIED;
107                 msg = "RADIO_ERROR_PERMISSION_DENIED";
108         }
109         LOGE("[%s] %s(0x%08x) : core fw error(0x%x)", func_name, msg, ret, code);
110         return ret;
111 }
112
113 static radio_state_e __convert_radio_state(MMRadioStateType state)
114 {
115         int converted_state = RADIO_STATE_READY;
116         LOGI("[%s] Enter state: %d", __func__, state);
117         switch (state) {
118
119         case MM_RADIO_STATE_PLAYING:
120                 converted_state = RADIO_STATE_PLAYING;
121                 break;
122         case MM_RADIO_STATE_SCANNING:
123                 converted_state = RADIO_STATE_SCANNING;
124                 break;
125         case MM_RADIO_STATE_NULL:
126         case MM_RADIO_STATE_READY:
127         default:
128                 converted_state = RADIO_STATE_READY;
129                 break;
130         }
131         LOGI("[%s] Leave converted_state: %d", __func__, converted_state);
132         return converted_state;
133 }
134
135 static int __set_callback(_radio_event_e type, radio_h radio, void *callback, void *user_data)
136 {
137         RADIO_INSTANCE_CHECK(radio);
138         RADIO_NULL_ARG_CHECK(callback);
139         radio_s *handle = (radio_s *)radio;
140         handle->user_cb[type] = callback;
141         handle->user_data[type] = user_data;
142         LOGI("[%s] Event type : %d", __FUNCTION__, type);
143         return RADIO_ERROR_NONE;
144 }
145
146 static int __unset_callback(_radio_event_e type, radio_h radio)
147 {
148         RADIO_INSTANCE_CHECK(radio);
149         radio_s *handle = (radio_s *)radio;
150         handle->user_cb[type] = NULL;
151         handle->user_data[type] = NULL;
152         LOGI("[%s] Event type : %d", __FUNCTION__, type);
153         return RADIO_ERROR_NONE;
154 }
155
156 static int __msg_callback(int message, void *param, void *user_data)
157 {
158         radio_s *handle = (radio_s *)user_data;
159         MMMessageParamType *msg = (MMMessageParamType *)param;
160         LOGI("[%s] Got message type : 0x%x", __FUNCTION__, message);
161         switch (message) {
162         case MM_MESSAGE_RADIO_SCAN_INFO:
163                 if (handle->user_cb[_RADIO_EVENT_TYPE_SCAN_INFO])
164                         ((radio_scan_updated_cb)handle->user_cb[_RADIO_EVENT_TYPE_SCAN_INFO])(msg->radio_scan.frequency, handle->user_data[_RADIO_EVENT_TYPE_SCAN_INFO]);
165                 break;
166         case MM_MESSAGE_RADIO_SCAN_STOP:
167                 if (handle->user_cb[_RADIO_EVENT_TYPE_SCAN_STOP])
168                         ((radio_scan_stopped_cb)handle->user_cb[_RADIO_EVENT_TYPE_SCAN_STOP])(handle->user_data[_RADIO_EVENT_TYPE_SCAN_STOP]);
169                 __unset_callback(_RADIO_EVENT_TYPE_SCAN_STOP, (radio_h)handle);
170                 __unset_callback(_RADIO_EVENT_TYPE_SCAN_INFO, (radio_h)handle);
171                 break;
172         case MM_MESSAGE_RADIO_SCAN_FINISH:
173                 if (handle->user_cb[_RADIO_EVENT_TYPE_SCAN_FINISH])
174                         ((radio_scan_completed_cb)handle->user_cb[_RADIO_EVENT_TYPE_SCAN_FINISH])(handle->user_data[_RADIO_EVENT_TYPE_SCAN_FINISH]);
175                 __unset_callback(_RADIO_EVENT_TYPE_SCAN_INFO, (radio_h)handle);
176                 break;
177         case MM_MESSAGE_RADIO_SEEK_FINISH:
178                 if (handle->user_cb[_RADIO_EVENT_TYPE_SEEK_FINISH]) {
179                         ((radio_seek_completed_cb)handle->user_cb[_RADIO_EVENT_TYPE_SEEK_FINISH])(msg->radio_scan.frequency, handle->user_data[_RADIO_EVENT_TYPE_SEEK_FINISH]);
180                         handle->seeking = false;
181                 }
182                 __unset_callback(_RADIO_EVENT_TYPE_SEEK_FINISH, (radio_h)handle);
183                 break;
184         case MM_MESSAGE_STATE_INTERRUPTED:
185                 if (msg->union_type == MM_MSG_UNION_STATE) {
186                         handle->state = __convert_radio_state(msg->state.current);
187                         if (handle->user_cb[_RADIO_EVENT_TYPE_INTERRUPT])
188                                 ((radio_interrupted_cb)handle->user_cb[_RADIO_EVENT_TYPE_INTERRUPT])(RADIO_INTERRUPTED_BY_RESOURCE_CONFLICT, handle->user_data[_RADIO_EVENT_TYPE_INTERRUPT]);
189                 }
190                 break;
191         case MM_MESSAGE_ERROR:
192                 __convert_error_code(msg->code, (char *)__FUNCTION__);
193                 break;
194         case MM_MESSAGE_RADIO_SCAN_START:
195                 LOGI("[%s] Scan Started", __FUNCTION__);
196                 break;
197         case MM_MESSAGE_STATE_CHANGED:
198                 handle->state = __convert_radio_state(msg->state.current);
199                 LOGI("[%s] State Changed --- from : %d , to : %d", __FUNCTION__, __convert_radio_state(msg->state.previous), handle->state);
200                 break;
201         case MM_MESSAGE_RADIO_SEEK_START:
202                 LOGI("[%s] Seek Started", __FUNCTION__);
203                 break;
204         default:
205                 break;
206         }
207         return 1;
208 }
209
210 static int __radio_check_system_info_feature_supported()
211 {
212         bool bValue = false;
213         int nRetVal = false;
214
215         nRetVal = system_info_get_platform_bool("http://tizen.org/feature/fmradio", &bValue);
216
217         if (nRetVal != SYSTEM_INFO_ERROR_NONE) {
218                 LOGE("[%s] SYSTEM_INFO_ERROR : ", __FUNCTION__);
219                 return false;
220         }
221
222         if (false == bValue)
223                 LOGI("system_info_get_platform_bool returned Unsupported feature capability\n");
224         else
225                 LOGI("system_info_get_platform_bool returned Supported status feature\n");
226
227         return bValue;
228 }
229
230 /*
231 * Public Implementation
232 */
233 int radio_create(radio_h *radio)
234 {
235         LOGI("[%s] Enter", __func__);
236         RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
237         RADIO_INSTANCE_CHECK(radio);
238         radio_s *handle;
239
240         handle = (radio_s *)malloc(sizeof(radio_s));
241         if (handle != NULL) {
242                 memset(handle, 0, sizeof(radio_s));
243         } else {
244                 LOGE("[%s] RADIO_ERROR_OUT_OF_MEMORY(0x%08x)", __FUNCTION__, RADIO_ERROR_OUT_OF_MEMORY);
245                 return RADIO_ERROR_OUT_OF_MEMORY;
246         }
247         int ret = mm_radio_create(&handle->mm_handle);
248         if (ret != MM_ERROR_NONE) {
249                 free(handle);
250                 handle = NULL;
251                 return __convert_error_code(ret, (char *)__FUNCTION__);
252         } else {
253                 *radio = (radio_h)handle;
254
255                 ret = mm_radio_set_message_callback(handle->mm_handle, __msg_callback, (void *)handle);
256                 if (ret != MM_ERROR_NONE)
257                         LOGW("[%s] Failed to set message callback function (0x%x)", __FUNCTION__, ret);
258
259                 ret = mm_radio_realize(handle->mm_handle);
260                 if (ret != MM_ERROR_NONE)
261                         return __convert_error_code(ret, (char *)__FUNCTION__);
262
263                 handle->state = RADIO_STATE_READY;
264                 handle->mute = false;
265                 handle->seeking = false;
266                 return RADIO_ERROR_NONE;
267         }
268 }
269
270 int radio_destroy(radio_h radio)
271 {
272         LOGI("[%s] Enter", __func__);
273         RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
274         RADIO_INSTANCE_CHECK(radio);
275         radio_s *handle = (radio_s *)radio;
276
277         int ret;
278         ret = mm_radio_unrealize(handle->mm_handle);
279         if (ret != MM_ERROR_NONE)
280                 LOGW("[%s] Failed to unrealize (0x%x)", __FUNCTION__, ret);
281
282         ret = mm_radio_destroy(handle->mm_handle);
283         if (ret != MM_ERROR_NONE) {
284                 return __convert_error_code(ret, (char *)__FUNCTION__);
285         } else {
286                 free(handle);
287                 handle = NULL;
288                 return RADIO_ERROR_NONE;
289         }
290 }
291
292 int radio_get_state(radio_h radio, radio_state_e *state)
293 {
294         LOGI("[%s] Enter", __func__);
295         RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
296         RADIO_INSTANCE_CHECK(radio);
297         RADIO_NULL_ARG_CHECK(state);
298         radio_s *handle = (radio_s *)radio;
299         MMRadioStateType currentStat = MM_RADIO_STATE_NULL;
300         int ret = mm_radio_get_state(handle->mm_handle, &currentStat);
301         if (ret != MM_ERROR_NONE) {
302                 *state = handle->state;
303                 return __convert_error_code(ret, (char *)__FUNCTION__);
304         } else {
305                 handle->state = __convert_radio_state(currentStat);
306                 *state = handle->state;
307                 return RADIO_ERROR_NONE;
308         }
309 }
310
311 int radio_start(radio_h radio)
312 {
313         LOGI("[%s] Enter", __func__);
314         RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
315         RADIO_INSTANCE_CHECK(radio);
316         radio_s *handle = (radio_s *)radio;
317         RADIO_STATE_CHECK(handle, RADIO_STATE_READY);
318
319         int ret = mm_radio_start(handle->mm_handle);
320         if (ret != MM_ERROR_NONE) {
321                 return __convert_error_code(ret, (char *)__FUNCTION__);
322         } else {
323                 handle->state = RADIO_STATE_PLAYING;
324                 return RADIO_ERROR_NONE;
325         }
326 }
327
328 int radio_stop(radio_h radio)
329 {
330         LOGI("[%s] Enter", __func__);
331         RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
332         RADIO_INSTANCE_CHECK(radio);
333         radio_s *handle = (radio_s *)radio;
334         RADIO_STATE_CHECK(handle, RADIO_STATE_PLAYING);
335
336         int ret = mm_radio_stop(handle->mm_handle);
337         if (ret != MM_ERROR_NONE) {
338                 return __convert_error_code(ret, (char *)__FUNCTION__);
339         } else {
340                 handle->state = RADIO_STATE_READY;
341                 return RADIO_ERROR_NONE;
342         }
343 }
344
345 int radio_seek_up(radio_h radio, radio_seek_completed_cb callback, void *user_data)
346 {
347         LOGI("[%s] Enter", __func__);
348         RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
349         RADIO_INSTANCE_CHECK(radio);
350         radio_s *handle = (radio_s *)radio;
351         RADIO_STATE_CHECK(handle, RADIO_STATE_PLAYING);
352
353         if (handle->seeking) {
354                 LOGI("radio is seeking, can't serve another request try again");
355                 return RADIO_ERROR_INVALID_OPERATION;
356         }
357
358         handle->seeking = true;
359
360         if (callback != NULL)
361                 __set_callback(_RADIO_EVENT_TYPE_SEEK_FINISH, radio, callback, user_data);
362         else
363                 __unset_callback(_RADIO_EVENT_TYPE_SEEK_FINISH, radio);
364
365         int ret = mm_radio_seek(handle->mm_handle, MM_RADIO_SEEK_UP);
366         if (ret != MM_ERROR_NONE)
367                 return __convert_error_code(ret, (char *)__FUNCTION__);
368         else
369                 return RADIO_ERROR_NONE;
370 }
371
372 int radio_seek_down(radio_h radio, radio_seek_completed_cb callback, void *user_data)
373 {
374         LOGI("[%s] Enter", __func__);
375         RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
376         RADIO_INSTANCE_CHECK(radio);
377         radio_s *handle = (radio_s *)radio;
378         RADIO_STATE_CHECK(handle, RADIO_STATE_PLAYING);
379
380         if (handle->seeking) {
381                 LOGI("radio is seeking, can't serve another request try again");
382                 return RADIO_ERROR_INVALID_OPERATION;
383         }
384
385         handle->seeking = true;
386
387         if (callback != NULL)
388                 __set_callback(_RADIO_EVENT_TYPE_SEEK_FINISH, radio, callback, user_data);
389         else
390                 __unset_callback(_RADIO_EVENT_TYPE_SEEK_FINISH, radio);
391
392         int ret = mm_radio_seek(handle->mm_handle, MM_RADIO_SEEK_DOWN);
393         if (ret != MM_ERROR_NONE)
394                 return __convert_error_code(ret, (char *)__FUNCTION__);
395         else
396                 return RADIO_ERROR_NONE;
397 }
398
399 int radio_set_frequency(radio_h radio, int frequency)
400 {
401         LOGI("[%s] Enter", __func__);
402         RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
403         RADIO_INSTANCE_CHECK(radio);
404         if (frequency < 87500 || frequency > 108000) {
405                 LOGE("[%s] RADIO_ERROR_INVALID_PARAMETER(0x%08x) : Out of range (87500 ~ 108000)", __FUNCTION__, RADIO_ERROR_INVALID_PARAMETER);
406                 return RADIO_ERROR_INVALID_PARAMETER;
407         }
408
409         radio_s *handle = (radio_s *)radio;
410         int ret = mm_radio_set_frequency(handle->mm_handle, frequency);
411         if (ret != MM_ERROR_NONE)
412                 return __convert_error_code(ret, (char *)__FUNCTION__);
413         else
414                 return RADIO_ERROR_NONE;
415 }
416
417 int radio_get_frequency(radio_h radio, int *frequency)
418 {
419         LOGI("[%s] Enter", __func__);
420         RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
421         RADIO_INSTANCE_CHECK(radio);
422         RADIO_NULL_ARG_CHECK(frequency);
423         radio_s *handle = (radio_s *)radio;
424
425         int freq;
426         int ret = mm_radio_get_frequency(handle->mm_handle, &freq);
427         if (ret != MM_ERROR_NONE) {
428                 return __convert_error_code(ret, (char *)__FUNCTION__);
429         } else {
430                 *frequency = freq;
431                 return RADIO_ERROR_NONE;
432         }
433 }
434
435 int radio_get_signal_strength(radio_h radio, int *strength)
436 {
437         LOGI("[%s] Enter", __func__);
438         RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
439         RADIO_INSTANCE_CHECK(radio);
440         RADIO_NULL_ARG_CHECK(strength);
441         radio_s *handle = (radio_s *)radio;
442
443         int _strength;
444         int ret = mm_radio_get_signal_strength(handle->mm_handle, &_strength);
445         if (ret != MM_ERROR_NONE) {
446                 return __convert_error_code(ret, (char *)__FUNCTION__);
447         } else {
448                 *strength = _strength;
449                 return RADIO_ERROR_NONE;
450         }
451 }
452
453 int radio_scan_start(radio_h radio, radio_scan_updated_cb callback, void *user_data)
454 {
455         LOGI("[%s] Enter", __func__);
456         RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
457         RADIO_INSTANCE_CHECK(radio);
458         radio_s *handle = (radio_s *)radio;
459
460         if (callback != NULL)
461                 __set_callback(_RADIO_EVENT_TYPE_SCAN_INFO, radio, callback, user_data);
462         else
463                 __unset_callback(_RADIO_EVENT_TYPE_SCAN_INFO, radio);
464
465         int ret = mm_radio_scan_start(handle->mm_handle);
466         if (ret != MM_ERROR_NONE) {
467                 return __convert_error_code(ret, (char *)__FUNCTION__);
468         } else {
469                 handle->state = RADIO_STATE_SCANNING;
470                 return RADIO_ERROR_NONE;
471         }
472 }
473
474 int radio_scan_stop(radio_h radio, radio_scan_stopped_cb callback, void *user_data)
475 {
476         LOGI("[%s] Enter", __func__);
477         RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
478         RADIO_INSTANCE_CHECK(radio);
479         radio_s *handle = (radio_s *)radio;
480         RADIO_STATE_CHECK(handle, RADIO_STATE_SCANNING);
481
482         if (handle->user_cb[_RADIO_EVENT_TYPE_SCAN_STOP]) {
483                 LOGW("[%s] Failed to stop scan (0x%x)", __FUNCTION__, RADIO_ERROR_INVALID_OPERATION);
484                 return RADIO_ERROR_INVALID_OPERATION;
485         }
486
487         if (callback != NULL)
488                 __set_callback(_RADIO_EVENT_TYPE_SCAN_STOP, radio, callback, user_data);
489         else
490                 __unset_callback(_RADIO_EVENT_TYPE_SCAN_STOP, radio);
491
492         int ret = mm_radio_scan_stop(handle->mm_handle);
493         if (ret != MM_ERROR_NONE)
494                 return __convert_error_code(ret, (char *)__FUNCTION__);
495         else
496                 return RADIO_ERROR_NONE;
497 }
498
499 int radio_set_mute(radio_h radio, bool muted)
500 {
501         LOGI("[%s] Enter", __func__);
502         RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
503         RADIO_INSTANCE_CHECK(radio);
504         radio_s *handle = (radio_s *)radio;
505
506         int ret = mm_radio_set_mute(handle->mm_handle, muted);
507         if (ret != MM_ERROR_NONE) {
508                 return __convert_error_code(ret, (char *)__FUNCTION__);
509         } else {
510                 handle->mute = muted;
511                 return RADIO_ERROR_NONE;
512         }
513 }
514
515 int radio_is_muted(radio_h radio, bool *muted)
516 {
517         LOGI("[%s] Enter", __func__);
518         RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
519         RADIO_INSTANCE_CHECK(radio);
520         RADIO_NULL_ARG_CHECK(muted);
521         radio_s *handle = (radio_s *)radio;
522         *muted = handle->mute;
523         return RADIO_ERROR_NONE;
524 }
525
526 int radio_set_scan_completed_cb(radio_h radio, radio_scan_completed_cb callback, void *user_data)
527 {
528         LOGI("[%s] Enter", __func__);
529         RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
530         return __set_callback(_RADIO_EVENT_TYPE_SCAN_FINISH, radio, callback, user_data);
531 }
532
533 int radio_unset_scan_completed_cb(radio_h radio)
534 {
535         LOGI("[%s] Enter", __func__);
536         RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
537         return __unset_callback(_RADIO_EVENT_TYPE_SCAN_FINISH, radio);
538 }
539
540 int radio_set_interrupted_cb(radio_h radio, radio_interrupted_cb callback, void *user_data)
541 {
542         LOGI("[%s] Enter", __func__);
543         RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
544         return __set_callback(_RADIO_EVENT_TYPE_INTERRUPT, radio, callback, user_data);
545 }
546
547 int radio_unset_interrupted_cb(radio_h radio)
548 {
549         LOGI("[%s] Enter", __func__);
550         RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
551         return __unset_callback(_RADIO_EVENT_TYPE_INTERRUPT, radio);
552 }
553
554 int radio_get_frequency_range(radio_h radio, int *min_freq, int *max_freq)
555 {
556         LOGI("[%s] Enter", __func__);
557         RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
558         RADIO_INSTANCE_CHECK(radio);
559         RADIO_NULL_ARG_CHECK(min_freq);
560         RADIO_NULL_ARG_CHECK(max_freq);
561         radio_s *handle = (radio_s *)radio;
562
563         unsigned int min = 0;
564         unsigned int max = 0;
565
566         int ret = mm_radio_get_region_frequency_range(handle->mm_handle, &min, &max);
567         if (ret != MM_ERROR_NONE) {
568                 return __convert_error_code(ret, (char *)__FUNCTION__);
569         } else {
570                 *min_freq = min;
571                 *max_freq = max;
572                 return RADIO_ERROR_NONE;
573         }
574 }
575
576 int radio_get_channel_spacing(radio_h radio, int *channel_spacing)
577 {
578         LOGI("[%s] Enter", __func__);
579         RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
580         RADIO_INSTANCE_CHECK(radio);
581
582         radio_s *handle = (radio_s *)radio;
583
584         int ret = mm_radio_get_channel_spacing(handle->mm_handle, channel_spacing);
585
586         if (ret != MM_ERROR_NONE)
587                 return __convert_error_code(ret, (char *)__FUNCTION__);
588         else
589                 return RADIO_ERROR_NONE;
590 }
591
592 int radio_set_volume(radio_h radio, float volume)
593 {
594         LOGI("[%s] Enter", __func__);
595         RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
596         RADIO_INSTANCE_CHECK(radio);
597         if (volume < 0.0 || volume > 1.0) {
598                 LOGE("[%s] RADIO_ERROR_INVALID_PARAMETER(0x%08x) : Out of range (0.0 ~ 1.0)", __FUNCTION__, RADIO_ERROR_INVALID_PARAMETER);
599                 return RADIO_ERROR_INVALID_PARAMETER;
600         }
601
602         radio_s *handle = (radio_s *)radio;
603         int ret = mm_radio_set_volume(handle->mm_handle, volume);
604         if (ret != MM_ERROR_NONE)
605                 return __convert_error_code(ret, (char *)__FUNCTION__);
606         else
607                 return RADIO_ERROR_NONE;
608 }
609
610 int radio_get_volume(radio_h radio, float *volume)
611 {
612         LOGI("[%s] Enter", __func__);
613         RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported());
614         RADIO_INSTANCE_CHECK(radio);
615         RADIO_NULL_ARG_CHECK(volume);
616         radio_s *handle = (radio_s *)radio;
617
618         float vol;
619         int ret = mm_radio_get_volume(handle->mm_handle, &vol);
620         if (ret != MM_ERROR_NONE) {
621                 return __convert_error_code(ret, (char *)__FUNCTION__);
622         } else {
623                 *volume = vol;
624                 return RADIO_ERROR_NONE;
625         }
626 }
627