Fix coverity/Svace issues (BAD_CHECK_OF_WAIT_COND, MISSING_UNLOCK, NULL_AFTER_DEREF)
[platform/core/multimedia/libmm-radio.git] / src / mm_radio.c
1 /*
2  * mm_radio.c
3  *
4  * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
5  *
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
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  */
19
20 /*===========================================================================================
21 |                                                                                                                                                                                       |
22 |  INCLUDE FILES                                                                                                                                                        |
23 |                                                                                                                                                                                       |
24 ========================================================================================== */
25
26 #include <string.h>
27 #include <glib.h>
28 #include <mm_types.h>
29 #include <mm_message.h>
30 #include "mm_radio.h"
31 #ifdef TIZEN_FEATURE_RADIO_HAL
32 #include "mm_radio_priv_hal.h"
33 #else
34 #include "mm_radio_priv_emul.h"
35 #endif
36 #include "mm_radio_utils.h"
37
38 /*===========================================================================================
39 |                                                                                                                                                                                       |
40 |  LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE                                                                                        |
41 |                                                                                                                                                                                       |
42 ========================================================================================== */
43
44 /*---------------------------------------------------------------------------
45 |    GLOBAL CONSTANT DEFINITIONS:                                                                                       |
46 ---------------------------------------------------------------------------*/
47
48 /*---------------------------------------------------------------------------
49 |    IMPORTED VARIABLE DECLARATIONS:                                                                            |
50 ---------------------------------------------------------------------------*/
51
52 /*---------------------------------------------------------------------------
53 |    IMPORTED FUNCTION DECLARATIONS:                                                                            |
54 ---------------------------------------------------------------------------*/
55
56 /*---------------------------------------------------------------------------
57 |    LOCAL #defines:                                                                                                            |
58 ---------------------------------------------------------------------------*/
59
60 /*---------------------------------------------------------------------------
61 |    LOCAL CONSTANT DEFINITIONS:                                                                                        |
62 ---------------------------------------------------------------------------*/
63
64 /*---------------------------------------------------------------------------
65 |    LOCAL DATA TYPE DEFINITIONS:                                                                                       |
66 ---------------------------------------------------------------------------*/
67
68 /*---------------------------------------------------------------------------
69 |    GLOBAL VARIABLE DEFINITIONS:                                                                                       |
70 ---------------------------------------------------------------------------*/
71
72 /*---------------------------------------------------------------------------
73 |    LOCAL VARIABLE DEFINITIONS:                                                                                        |
74 ---------------------------------------------------------------------------*/
75
76 /*---------------------------------------------------------------------------
77 |    LOCAL FUNCTION PROTOTYPES:                                                                                         |
78 ---------------------------------------------------------------------------*/
79
80 /*===========================================================================
81 |                                                                                                                                                       |
82 |  FUNCTION DEFINITIONS                                                                                                         |
83 |                                                                                                                                                       |
84 ========================================================================== */
85
86 int mm_radio_create(MMHandleType *hradio)
87 {
88         int result = MM_ERROR_NONE;
89         mm_radio_t *new_radio = NULL;
90
91         MMRADIO_LOG_FENTER();
92
93         MMRADIO_RETURN_VAL_IF_FAIL(hradio, MM_ERROR_RADIO_NOT_INITIALIZED);
94
95         /* alloc radio structure */
96         new_radio = (mm_radio_t *)malloc(sizeof(mm_radio_t));
97         if (!new_radio) {
98                 MMRADIO_LOG_CRITICAL("cannot allocate memory for radio");
99                 goto ERROR;
100         }
101         memset(new_radio, 0, sizeof(mm_radio_t));
102
103         /* internal creation stuffs */
104         result = _mmradio_create_radio(new_radio);
105
106         if (result != MM_ERROR_NONE) {
107                 MMRADIO_LOG_ERROR("radio creation failed");
108                 goto ERROR;
109         }
110
111         *hradio = (MMHandleType)new_radio;
112
113         MMRADIO_LOG_FLEAVE();
114
115         return result;
116
117 ERROR:
118
119         if (new_radio)
120                 MMRADIO_FREEIF(new_radio);
121
122         *hradio = (MMHandleType)0;
123
124         MMRADIO_LOG_FLEAVE();
125
126         /* FIXIT : need to specify more error case */
127         return result;
128 }
129
130 int mm_radio_destroy(MMHandleType hradio)
131 {
132         int result = MM_ERROR_NONE;
133         mm_radio_t *radio = (mm_radio_t *)hradio;
134
135         MMRADIO_LOG_FENTER();
136
137         MMRADIO_RETURN_VAL_IF_FAIL(radio, MM_ERROR_RADIO_NOT_INITIALIZED);
138
139         result = _mmradio_destroy(radio);
140
141         if (result != MM_ERROR_NONE)
142                 MMRADIO_LOG_ERROR("failed to destroy radio");
143
144         /* free radio */
145         MMRADIO_FREEIF(radio);
146
147         MMRADIO_LOG_FLEAVE();
148
149         return result;
150 }
151
152 int mm_radio_realize(MMHandleType hradio)
153 {
154         int result = MM_ERROR_NONE;
155         mm_radio_t *radio = (mm_radio_t *)hradio;
156
157         MMRADIO_LOG_FENTER();
158
159         MMRADIO_RETURN_VAL_IF_FAIL(radio, MM_ERROR_RADIO_NOT_INITIALIZED);
160
161         MMRADIO_CMD_LOCK(radio);
162
163         result = _mmradio_realize(radio);
164
165         MMRADIO_CMD_UNLOCK(radio);
166
167         MMRADIO_LOG_FLEAVE();
168
169         return result;
170 }
171
172 int mm_radio_unrealize(MMHandleType hradio)
173 {
174         int result = MM_ERROR_NONE;
175         mm_radio_t *radio = (mm_radio_t *)hradio;
176         MMRadioStateType state = 0;
177
178         MMRADIO_LOG_FENTER();
179
180         MMRADIO_RETURN_VAL_IF_FAIL(radio, MM_ERROR_RADIO_NOT_INITIALIZED);
181
182         mm_radio_get_state((hradio), &state);
183         MMRADIO_LOG_DEBUG("mm_radio_unrealize state: %d", state);
184
185         if (state == MM_RADIO_STATE_SCANNING)
186                 mm_radio_scan_stop(hradio);
187
188         MMRADIO_CMD_LOCK(radio);
189
190         result = _mmradio_unrealize(radio);
191
192         MMRADIO_CMD_UNLOCK(radio);
193
194         MMRADIO_LOG_FLEAVE();
195
196         return result;
197 }
198
199 int mm_radio_set_message_callback(MMHandleType hradio, MMMessageCallback callback, void *user_param)
200 {
201         int result = MM_ERROR_NONE;
202         mm_radio_t *radio = (mm_radio_t *)hradio;
203
204         MMRADIO_LOG_FENTER();
205
206         MMRADIO_RETURN_VAL_IF_FAIL(radio, MM_ERROR_RADIO_NOT_INITIALIZED);
207
208         MMRADIO_CMD_LOCK(radio);
209
210         result = _mmradio_set_message_callback(radio, callback, user_param);
211
212         MMRADIO_CMD_UNLOCK(radio);
213
214         MMRADIO_LOG_FLEAVE();
215
216         return result;
217 }
218
219 int mm_radio_get_state(MMHandleType hradio, MMRadioStateType *pState)
220 {
221         int result = MM_ERROR_NONE;
222         mm_radio_t *radio = (mm_radio_t *)hradio;
223         int state = 0;
224
225         MMRADIO_LOG_FENTER();
226
227         MMRADIO_RETURN_VAL_IF_FAIL(radio, MM_ERROR_RADIO_NOT_INITIALIZED);
228         MMRADIO_RETURN_VAL_IF_FAIL(pState, MM_ERROR_COMMON_INVALID_ARGUMENT);
229
230         MMRADIO_CMD_LOCK(radio);
231
232         result = _mmradio_get_state(radio, &state);
233
234         *pState = state;
235
236         MMRADIO_CMD_UNLOCK(radio);
237
238         MMRADIO_LOG_FLEAVE();
239
240         return result;
241 }
242
243 int mm_radio_start(MMHandleType hradio)
244 {
245         int result = MM_ERROR_NONE;
246         mm_radio_t *radio = (mm_radio_t *)hradio;
247
248         MMRADIO_LOG_FENTER();
249
250         MMRADIO_RETURN_VAL_IF_FAIL(radio, MM_ERROR_RADIO_NOT_INITIALIZED);
251
252         MMRADIO_CMD_LOCK(radio);
253
254         result = _mmradio_start(radio);
255
256         MMRADIO_CMD_UNLOCK(radio);
257
258         MMRADIO_LOG_FLEAVE();
259
260         return result;
261 }
262
263 int mm_radio_stop(MMHandleType hradio)
264 {
265         int result = MM_ERROR_NONE;
266         mm_radio_t *radio = (mm_radio_t *)hradio;
267
268         MMRADIO_LOG_FENTER();
269
270         MMRADIO_RETURN_VAL_IF_FAIL(radio, MM_ERROR_RADIO_NOT_INITIALIZED);
271
272         MMRADIO_CMD_LOCK(radio);
273
274         result = _mmradio_stop(radio);
275
276         MMRADIO_CMD_UNLOCK(radio);
277
278         MMRADIO_LOG_FLEAVE();
279
280         return result;
281 }
282
283 int mm_radio_seek(MMHandleType hradio, MMRadioSeekDirectionType direction)
284 {
285         int result = MM_ERROR_NONE;
286         mm_radio_t *radio = (mm_radio_t *)hradio;
287
288         MMRADIO_LOG_FENTER();
289
290         MMRADIO_RETURN_VAL_IF_FAIL(radio, MM_ERROR_RADIO_NOT_INITIALIZED);
291         MMRADIO_RETURN_VAL_IF_FAIL(direction >= MM_RADIO_SEEK_UP
292                 && direction <= MM_RADIO_SEEK_DOWN, MM_ERROR_INVALID_ARGUMENT);
293
294         MMRADIO_CMD_LOCK(radio);
295
296         radio->seek_direction = direction;
297
298         result = _mmradio_seek(radio, direction);
299
300         MMRADIO_CMD_UNLOCK(radio);
301
302         MMRADIO_LOG_FLEAVE();
303
304         return result;
305 }
306
307 int mm_radio_set_frequency(MMHandleType hradio, int freq)
308 {
309         int result = MM_ERROR_NONE;
310         mm_radio_t *radio = (mm_radio_t *)hradio;
311
312         MMRADIO_LOG_FENTER();
313
314         MMRADIO_RETURN_VAL_IF_FAIL(radio, MM_ERROR_RADIO_NOT_INITIALIZED);
315
316         MMRADIO_CMD_LOCK(radio);
317
318         result = _mmradio_set_frequency(radio, freq);
319
320         MMRADIO_CMD_UNLOCK(radio);
321
322         MMRADIO_LOG_FLEAVE();
323
324         return result;
325 }
326
327 int mm_radio_get_frequency(MMHandleType hradio, int *pFreq)
328 {
329         int result = MM_ERROR_NONE;
330         mm_radio_t *radio = (mm_radio_t *)hradio;
331         int freq = 0;
332
333         MMRADIO_LOG_FENTER();
334
335         MMRADIO_RETURN_VAL_IF_FAIL(radio, MM_ERROR_RADIO_NOT_INITIALIZED);
336         MMRADIO_RETURN_VAL_IF_FAIL(pFreq, MM_ERROR_INVALID_ARGUMENT);
337
338         MMRADIO_CMD_LOCK(radio);
339
340         result = _mmradio_get_frequency(radio, &freq);
341
342         *pFreq = freq;
343
344         MMRADIO_CMD_UNLOCK(radio);
345
346         MMRADIO_LOG_FLEAVE();
347
348         return result;
349 }
350
351 int mm_radio_scan_start(MMHandleType hradio)
352 {
353         int result = MM_ERROR_NONE;
354         mm_radio_t *radio = (mm_radio_t *)hradio;
355
356         MMRADIO_LOG_FENTER();
357
358         MMRADIO_RETURN_VAL_IF_FAIL(radio, MM_ERROR_RADIO_NOT_INITIALIZED);
359
360         MMRADIO_CMD_LOCK(radio);
361
362         result = _mmradio_start_scan(radio);
363
364         MMRADIO_CMD_UNLOCK(radio);
365
366         MMRADIO_LOG_FLEAVE();
367
368         return result;
369 }
370
371 int mm_radio_scan_stop(MMHandleType hradio)
372 {
373         int result = MM_ERROR_NONE;
374         mm_radio_t *radio = (mm_radio_t *)hradio;
375
376         MMRADIO_LOG_FENTER();
377
378         MMRADIO_RETURN_VAL_IF_FAIL(radio, MM_ERROR_RADIO_NOT_INITIALIZED);
379
380         MMRADIO_CMD_LOCK(radio);
381
382         result = _mmradio_stop_scan(radio);
383
384         MMRADIO_CMD_UNLOCK(radio);
385
386         MMRADIO_LOG_FLEAVE();
387
388         return result;
389 }
390
391 int mm_radio_set_mute(MMHandleType hradio, bool muted)
392 {
393         int result = MM_ERROR_NONE;
394         mm_radio_t *radio = (mm_radio_t *)hradio;
395
396         MMRADIO_LOG_FENTER();
397
398         MMRADIO_RETURN_VAL_IF_FAIL(radio, MM_ERROR_RADIO_NOT_INITIALIZED);
399
400         MMRADIO_CMD_LOCK(radio);
401
402         if (muted)
403                 result = _mmradio_mute(radio);
404         else
405                 result = _mmradio_unmute(radio);
406
407         MMRADIO_CMD_UNLOCK(radio);
408
409         MMRADIO_LOG_FLEAVE();
410
411         return result;
412 }
413
414 int mm_radio_get_signal_strength(MMHandleType hradio, int *value)
415 {
416         MMRADIO_RETURN_VAL_IF_FAIL(hradio, MM_ERROR_RADIO_NOT_INITIALIZED);
417         MMRADIO_RETURN_VAL_IF_FAIL(value, MM_ERROR_INVALID_ARGUMENT);
418
419         MMRADIO_LOG_FENTER();
420
421         int ret = MM_ERROR_NONE;
422
423         mm_radio_t *radio = (mm_radio_t *)hradio;
424
425         MMRADIO_CMD_LOCK(radio);
426
427         ret = _mm_radio_get_signal_strength(radio, value);
428
429         MMRADIO_CMD_UNLOCK(radio);
430
431         MMRADIO_LOG_INFO("signal strength = %d", *value);
432         MMRADIO_LOG_FLEAVE();
433
434         return ret;
435 }
436
437 int mm_radio_get_region_type(MMHandleType hradio, MMRadioRegionType *type)
438 {
439         MMRADIO_LOG_FENTER();
440         MMRADIO_RETURN_VAL_IF_FAIL(hradio, MM_ERROR_RADIO_NOT_INITIALIZED);
441         MMRADIO_RETURN_VAL_IF_FAIL(type, MM_ERROR_INVALID_ARGUMENT);
442
443         int result = MM_ERROR_NONE;
444         mm_radio_t *radio = (mm_radio_t *)hradio;
445         MMRadioRegionType cur_type = MM_RADIO_REGION_GROUP_NONE;
446
447         result = _mmradio_get_region_type(radio, &cur_type);
448
449         if (result == MM_ERROR_NONE)
450                 *type = cur_type;
451
452         MMRADIO_LOG_FLEAVE();
453         return result;
454 }
455
456 int mm_radio_get_region_frequency_range(MMHandleType hradio, unsigned int *min, unsigned int *max)
457 {
458         MMRADIO_LOG_FENTER();
459
460         MMRADIO_RETURN_VAL_IF_FAIL(hradio, MM_ERROR_RADIO_NOT_INITIALIZED);
461         MMRADIO_RETURN_VAL_IF_FAIL(min && max, MM_ERROR_INVALID_ARGUMENT);
462
463         int result = MM_ERROR_NONE;
464         mm_radio_t *radio = (mm_radio_t *)hradio;
465         unsigned int min_freq = 0;
466         unsigned int max_freq = 0;
467
468         result = _mmradio_get_region_frequency_range(radio, &min_freq, &max_freq);
469
470         if (result == MM_ERROR_NONE) {
471                 *min = min_freq;
472                 *max = max_freq;
473         }
474
475         MMRADIO_LOG_FLEAVE();
476         return result;
477 }
478
479 int mm_radio_get_channel_spacing(MMHandleType hradio, int *channel_spacing)
480 {
481         MMRADIO_LOG_FENTER();
482
483         MMRADIO_RETURN_VAL_IF_FAIL(hradio, MM_ERROR_RADIO_NOT_INITIALIZED);
484         MMRADIO_RETURN_VAL_IF_FAIL(channel_spacing, MM_ERROR_INVALID_ARGUMENT);
485
486         int result = MM_ERROR_NONE;
487         mm_radio_t *radio = (mm_radio_t *)hradio;
488         unsigned int ch_spacing = 0;
489
490         result = _mmradio_get_channel_spacing(radio, &ch_spacing);
491
492         if (result == MM_ERROR_NONE)
493                 *channel_spacing = ch_spacing;
494
495         MMRADIO_LOG_FLEAVE();
496         return result;
497 }
498
499 int mm_radio_set_volume(MMHandleType hradio, float volume)
500 {
501         int result = MM_ERROR_NONE;
502         mm_radio_t *radio = (mm_radio_t *)hradio;
503
504         MMRADIO_LOG_FENTER();
505
506         MMRADIO_RETURN_VAL_IF_FAIL(radio, MM_ERROR_RADIO_NOT_INITIALIZED);
507
508         MMRADIO_CMD_LOCK(radio);
509
510         result = _mmradio_set_volume(radio, volume);
511
512         MMRADIO_CMD_UNLOCK(radio);
513
514         MMRADIO_LOG_FLEAVE();
515
516         return result;
517 }
518
519 int mm_radio_get_volume(MMHandleType hradio, float *pVolume)
520 {
521         int result = MM_ERROR_NONE;
522         mm_radio_t *radio = (mm_radio_t *)hradio;
523         float volume = 0.0;
524
525         MMRADIO_LOG_FENTER();
526
527         MMRADIO_RETURN_VAL_IF_FAIL(radio, MM_ERROR_RADIO_NOT_INITIALIZED);
528         MMRADIO_RETURN_VAL_IF_FAIL(pVolume, MM_ERROR_INVALID_ARGUMENT);
529
530         MMRADIO_CMD_LOCK(radio);
531
532         result = _mmradio_get_volume(radio, &volume);
533         if (result == MM_ERROR_NONE)
534                 *pVolume = volume;
535
536         MMRADIO_CMD_UNLOCK(radio);
537
538         MMRADIO_LOG_FLEAVE();
539
540         return result;
541 }
542