Name: libmm-radio
Summary: Multimedia Framework Radio Library
-Version: 0.3.5
+Version: 0.3.6
Release: 0
Group: System/Libraries
License: Apache-2.0
includelibmmfradiodir = $(includedir)/mmf
includelibmmfradio_HEADERS = include/mm_radio.h
-libmmfradio_la_SOURCES = mm_radio.c
+libmmfradio_la_SOURCES = mm_radio.c mm_radio_rm.c mm_radio_priv_common.c
libmmfradio_la_CFLAGS = -I. -I./include \
$(MMCOMMON_CFLAGS) \
$(RC_LIBS)
if ENABLE_EMULATOR
-libmmfradio_la_SOURCES += mm_radio_priv_emulator.c mm_radio_rm.c
+libmmfradio_la_SOURCES += mm_radio_priv_emulator.c
libmmfradio_la_CFLAGS += $(GST_CFLAGS) \
$(GSTAPP_CFLAGS)
libmmfradio_la_LIBADD += $(GST_LIBS) \
$(GSTAPP_LIBS)
else
-libmmfradio_la_SOURCES += mm_radio_priv_hal.c mm_radio_rm.c
+libmmfradio_la_SOURCES += mm_radio_priv_hal.c
libmmfradio_la_CFLAGS += $(HAL_API_RADIO_CFLAGS)
--- /dev/null
+/*
+ * mm_radio_priv.h
+ *
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __MM_RADIO_PRIV_H__
+#define __MM_RADIO_PRIV_H__
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <float.h>
+#include <string.h>
+#include <malloc.h>
+#include <pthread.h>
+#include <glib.h>
+#include <mm_error.h>
+#include <mm_message.h>
+#ifdef TIZEN_FEATURE_RADIO_HAL
+#include <media/sound_manager.h>
+#include <media/sound_manager_internal.h>
+#else
+#include <gst/gst.h>
+#include <gst/gstbuffer.h>
+#endif
+#include "mm_radio.h"
+#include "mm_radio_utils.h"
+#include "mm_radio_rm.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#define DEFAULT_FREQ 107700
+#define RADIO_DEFAULT_REGION MM_RADIO_REGION_GROUP_USA
+
+typedef enum {
+ MMRADIO_COMMAND_CREATE = 0,
+ MMRADIO_COMMAND_DESTROY,
+ MMRADIO_COMMAND_REALIZE,
+ MMRADIO_COMMAND_UNREALIZE,
+ MMRADIO_COMMAND_START,
+ MMRADIO_COMMAND_STOP,
+ MMRADIO_COMMAND_START_SCAN,
+ MMRADIO_COMMAND_STOP_SCAN,
+ MMRADIO_COMMAND_SET_FREQ,
+ MMRADIO_COMMAND_GET_FREQ,
+ MMRADIO_COMMAND_MUTE,
+ MMRADIO_COMMAND_UNMUTE,
+ MMRADIO_COMMAND_SEEK,
+ MMRADIO_COMMAND_SET_REGION,
+ MMRADIO_COMMAND_GET_REGION,
+ MMRADIO_COMMAND_SET_VOLUME,
+ MMRADIO_COMMAND_GET_VOLUME,
+ MMRADIO_COMMAND_NUM
+} MMRadioCommand;
+
+/* max and mix frequency types, KHz */
+typedef enum {
+ MM_RADIO_FREQ_NONE = 0,
+ /* min band types */
+ MM_RADIO_FREQ_MIN_76100_KHZ = 76100,
+ MM_RADIO_FREQ_MIN_87500_KHZ = 87500,
+ MM_RADIO_FREQ_MIN_88100_KHZ = 88100,
+ /* max band types */
+ MM_RADIO_FREQ_MAX_89900_KHZ = 89900,
+ MM_RADIO_FREQ_MAX_108000_KHZ = 108000,
+} MMRadioFreqTypes;
+
+/* de-emphasis types */
+typedef enum {
+ MM_RADIO_DEEMPHASIS_NONE = 0,
+ MM_RADIO_DEEMPHASIS_50_US,
+ MM_RADIO_DEEMPHASIS_75_US,
+} MMRadioDeemphasis;
+
+/* radio region settings */
+typedef struct {
+ MMRadioRegionType country;
+ MMRadioDeemphasis deemphasis; // unit : us
+ MMRadioFreqTypes band_min; // <- freq. range, unit : KHz
+ MMRadioFreqTypes band_max; // ->
+ int channel_spacing; // TBD
+} MMRadioRegion_t;
+
+typedef struct {
+ pthread_t thread;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ int thread_id;
+ bool is_running;
+ bool stop;
+ bool thread_exit;
+} MMRadioThread_t;
+
+typedef enum {
+ MM_RADIO_MSG_DESTROY = 0,
+ MM_RADIO_MSG_SCAN_INFO,
+ MM_RADIO_MSG_SCAN_STOPPED,
+ MM_RADIO_MSG_SCAN_FINISHED,
+ MM_RADIO_MSG_SEEK_FINISHED,
+ MM_RADIO_MSG_STATE_INTERRUPTED,
+ MM_RADIO_MSG_NUM
+} MMRadioMsgTypes;
+
+typedef struct {
+ bool destroy;
+ MMRadioMsgTypes msg_type;
+ int data;
+} mm_radio_msg_t;
+
+typedef enum {
+ MM_RADIO_THREAD_MSG = 0,
+ MM_RADIO_THREAD_SEEK,
+ MM_RADIO_THREAD_SCAN,
+ MM_RADIO_THREAD_NUM
+} MMRadioThreadTypes;
+
+#ifndef TIZEN_FEATURE_RADIO_HAL
+typedef struct _mm_radio_gstreamer_s {
+ GMainLoop *loop;
+ GstElement *pipeline;
+ GstElement *audiosrc;
+ GstElement *converter;
+ GstElement *volume;
+ GstElement *audiosink;
+} mm_radio_gstreamer_s;
+#endif
+
+typedef struct {
+ /* radio state */
+ int current_state;
+ int old_state;
+ int pending_state;
+
+ int cmd;
+
+ /* command lock */
+ pthread_mutex_t cmd_lock;
+
+ /* radio attributes */
+ MMHandleType *attrs;
+
+ MMRadioThread_t thread[MM_RADIO_THREAD_NUM];
+
+ /* message callback */
+ GAsyncQueue *msg_queue;
+ MMMessageCallback msg_cb;
+ void *msg_cb_param;
+
+ bool is_ready;
+
+ /* seek */
+ int prev_seek_freq;
+ pthread_mutex_t seek_mutex;
+ MMRadioSeekDirectionType seek_direction;
+#ifdef TIZEN_FEATURE_RADIO_HAL
+ bool is_muted;
+ bool seek_unmute;
+
+ sound_stream_info_h stream_info;
+ virtual_sound_stream_h vstream;
+ void *hal_radio;
+#else
+ mm_radio_gstreamer_s *pipeline;
+#endif
+
+ int freq;
+
+ float local_volume;
+
+ /* region settings */
+ MMRadioRegion_t region_setting;
+
+ radio_resource_s resource;
+
+ int interrupted_by_resource_conflict;
+
+} mm_radio_t;
+
+int _mmradio_create_radio(mm_radio_t *radio);
+int _mmradio_destroy(mm_radio_t *radio);
+int _mmradio_realize(mm_radio_t *radio);
+int _mmradio_unrealize(mm_radio_t *radio);
+int _mmradio_set_message_callback(mm_radio_t *radio, MMMessageCallback callback, void *user_param);
+int _mmradio_get_state(mm_radio_t *radio, int *pState);
+int _mmradio_set_frequency(mm_radio_t *radio, int freq);
+int _mmradio_get_frequency(mm_radio_t *radio, int *pFreq);
+int _mmradio_mute(mm_radio_t *radio);
+int _mmradio_unmute(mm_radio_t *radio);
+int _mmradio_start(mm_radio_t *radio);
+int _mmradio_stop(mm_radio_t *radio);
+int _mmradio_seek(mm_radio_t *radio, MMRadioSeekDirectionType direction);
+int _mmradio_start_scan(mm_radio_t *radio);
+int _mmradio_stop_scan(mm_radio_t *radio);
+int _mmradio_get_signal_strength(mm_radio_t *radio, int *strength);
+int _mmradio_apply_region(mm_radio_t *radio, MMRadioRegionType region, bool update);
+int _mmradio_get_region_type(mm_radio_t *radio, MMRadioRegionType *type);
+int _mmradio_get_region_frequency_range(mm_radio_t *radio, unsigned int *min_freq, unsigned int *max_freq);
+int _mmradio_get_channel_spacing(mm_radio_t *radio, unsigned int *ch_spacing);
+int _mmradio_set_volume(mm_radio_t *radio, float volume);
+int _mmradio_get_volume(mm_radio_t *radio, float *pVolume);
+
+bool _mmradio_common_is_tunable_frequency(mm_radio_t *radio, int freq);
+int _mmradio_common_create_threads(mm_radio_t *radio, void **function);
+void _mmradio_common_destroy_threads(mm_radio_t *radio);
+void _mmradio_common_msg_push(mm_radio_t *radio, MMRadioMsgTypes msg_type, int msg_data);
+bool _mmradio_common_set_state(mm_radio_t *radio, int new_state);
+int _mmradio_common_check_state(mm_radio_t *radio, MMRadioCommand command);
+bool _mmradio_common_post_message(mm_radio_t *radio, enum MMMessageType msgtype, MMMessageParamType *param);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MM_RADIO_PRIV_H__ */
+++ /dev/null
-/*
- * mm_radio_priv.h
- *
- * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef __MM_Radio_INTERNAL_H__
-#define __MM_Radio_INTERNAL_H__
-
-/*===========================================================================================
- INCLUDE FILES
-========================================================================================== */
-#include <stdio.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <malloc.h>
-#include <pthread.h>
-#include <signal.h>
-
-#include <mm_types.h>
-#include <mm_message.h>
-
-#include "mm_radio.h"
-#include "mm_radio_utils.h"
-#include "mm_radio_rm.h"
-
-#include <linux/videodev2.h>
-
-#include <gst/gst.h>
-#include <gst/gstbuffer.h>
-
-#include <glib.h>
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/*===========================================================================================
- GLOBAL DEFINITIONS AND DECLARATIONS FOR MODULE
-========================================================================================== */
-
-/*---------------------------------------------------------------------------
- GLOBAL #defines:
----------------------------------------------------------------------------*/
-#define SAMPLEDELAY 15000
-
-/* si470x dependent define */
-#define SYSCONFIG1 4 /* System Configuration 1 */
-#define SYSCONFIG1_RDS 0x1000 /* bits 12..12: RDS Enable */
-#define SYSCONFIG1_RDS_OFFSET 12 /* bits 12..12: RDS Enable Offset */
-
-#define SYSCONFIG2 5 /* System Configuration 2 */
-#define SYSCONFIG2_SEEKTH 0xff00 /* bits 15..08: RSSI Seek Threshold */
-#define SYSCONFIG2_SEEKTH_OFFSET 8 /* bits 15..08: RSSI Seek Threshold Offset */
-
-#define SYSCONFIG3 6 /* System Configuration 3 */
-#define SYSCONFIG3_SKSNR 0x00f0 /* bits 07..04: Seek SNR Threshold */
-#define SYSCONFIG3_SKCNT 0x000f /* bits 03..00: Seek FM Impulse Detection Threshold */
-#define SYSCONFIG3_SKSNR_OFFSET 4 /* bits 07..04: Seek SNR Threshold Offset */
-#define SYSCONFIG3_SKCNT_OFFSET 0 /* bits 03..00: Seek FM Impulse Detection Threshold Offset */
-
-#define DEFAULT_CHIP_MODEL "radio-si470x"
-
-/*---------------------------------------------------------------------------
- GLOBAL CONSTANT DEFINITIONS:
----------------------------------------------------------------------------*/
-typedef enum {
- MMRADIO_COMMAND_CREATE = 0,
- MMRADIO_COMMAND_DESTROY,
- MMRADIO_COMMAND_REALIZE,
- MMRADIO_COMMAND_UNREALIZE,
- MMRADIO_COMMAND_START,
- MMRADIO_COMMAND_STOP,
- MMRADIO_COMMAND_START_SCAN,
- MMRADIO_COMMAND_STOP_SCAN,
- MMRADIO_COMMAND_SET_FREQ,
- MMRADIO_COMMAND_GET_FREQ,
- MMRADIO_COMMAND_MUTE,
- MMRADIO_COMMAND_UNMUTE,
- MMRADIO_COMMAND_SEEK,
- MMRADIO_COMMAND_SET_REGION,
- MMRADIO_COMMAND_GET_REGION,
- MMRADIO_COMMAND_SET_VOLUME,
- MMRADIO_COMMAND_GET_VOLUME,
- MMRADIO_COMMAND_NUM
-} MMRadioCommand;
-
-/* max and mix frequency types, KHz */
-typedef enum {
- MM_RADIO_FREQ_NONE = 0,
- /* min band types */
- MM_RADIO_FREQ_MIN_76100_KHZ = 76100,
- MM_RADIO_FREQ_MIN_87500_KHZ = 87500,
- MM_RADIO_FREQ_MIN_88100_KHZ = 88100,
- /* max band types */
- MM_RADIO_FREQ_MAX_89900_KHZ = 89900,
- MM_RADIO_FREQ_MAX_108000_KHZ = 108000,
-} MMRadioFreqTypes;
-
-/* de-emphasis types */
-typedef enum {
- MM_RADIO_DEEMPHASIS_NONE = 0,
- MM_RADIO_DEEMPHASIS_50_US,
- MM_RADIO_DEEMPHASIS_75_US,
-} MMRadioDeemphasis;
-
-/* radio region settings */
-typedef struct {
- MMRadioRegionType country;
- MMRadioDeemphasis deemphasis; // unit : us
- MMRadioFreqTypes band_min; // <- freq. range, unit : KHz
- MMRadioFreqTypes band_max; // ->
- int channel_spacing; // TBD
-} MMRadioRegion_t;
-
-typedef struct {
- pthread_t thread;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- int thread_id;
- bool is_running;
- bool stop;
- bool thread_exit;
-} MMRadioThread_t;
-
-typedef enum {
- MM_RADIO_MSG_DESTROY = 0,
- MM_RADIO_MSG_SCAN_INFO,
- MM_RADIO_MSG_SCAN_STOPPED,
- MM_RADIO_MSG_SCAN_FINISHED,
- MM_RADIO_MSG_SEEK_FINISHED,
- MM_RADIO_MSG_STATE_INTERRUPTED,
- MM_RADIO_MSG_NUM
-} MMRadioMsgTypes;
-
-typedef struct {
- bool destroy;
- MMRadioMsgTypes msg_type;
- int data;
-} mm_radio_msg_t;
-
-typedef enum {
- MM_RADIO_THREAD_MSG = 0,
- MM_RADIO_THREAD_SEEK,
- MM_RADIO_THREAD_SCAN,
- MM_RADIO_THREAD_NUM
-} MMRadioThreadTypes;
-
-/*---------------------------------------------------------------------------
- GLOBAL DATA TYPE DEFINITIONS:
----------------------------------------------------------------------------*/
-
-typedef struct _mm_radio_gstreamer_s {
- GMainLoop *loop;
- GstElement *pipeline;
- GstElement *audiosrc;
- GstElement *converter;
- GstElement *volume;
- GstElement *audiosink;
-} mm_radio_gstreamer_s;
-
-typedef struct {
- /* radio state */
- int current_state;
- int old_state;
- int pending_state;
-
- int cmd;
-
- /* command lock */
- pthread_mutex_t cmd_lock;
-
- /* radio attributes */
- MMHandleType *attrs;
-
- MMRadioThread_t thread[MM_RADIO_THREAD_NUM];
-
- /* message callback */
- GAsyncQueue *msg_queue;
- MMMessageCallback msg_cb;
- void *msg_cb_param;
-
- /* radio device fd */
- int radio_fd;
-
- /* seek */
- int prev_seek_freq;
- MMRadioSeekDirectionType seek_direction;
-
- int freq;
- mm_radio_gstreamer_s *pipeline;
-
- radio_resource_s resource;
-
- int interrupted_by_resource_conflict;
-
- float local_volume;
-
- /* region settings */
- MMRadioRegion_t region_setting;
-} mm_radio_t;
-
-/*===========================================================================================
- GLOBAL FUNCTION PROTOTYPES
-========================================================================================== */
-int _mmradio_create_radio(mm_radio_t *radio);
-int _mmradio_destroy(mm_radio_t *radio);
-int _mmradio_realize(mm_radio_t *radio);
-int _mmradio_unrealize(mm_radio_t *radio);
-int _mmradio_set_message_callback(mm_radio_t *radio, MMMessageCallback callback, void *user_param);
-int _mmradio_get_state(mm_radio_t *radio, int *pState);
-int _mmradio_set_frequency(mm_radio_t *radio, int freq);
-int _mmradio_get_frequency(mm_radio_t *radio, int *pFreq);
-int _mmradio_mute(mm_radio_t *radio);
-int _mmradio_unmute(mm_radio_t *radio);
-int _mmradio_start(mm_radio_t *radio);
-int _mmradio_stop(mm_radio_t *radio);
-int _mmradio_seek(mm_radio_t *radio, MMRadioSeekDirectionType direction);
-int _mmradio_start_scan(mm_radio_t *radio);
-int _mmradio_stop_scan(mm_radio_t *radio);
-int _mmradio_get_signal_strength(mm_radio_t *radio, int *strength);
-int _mmradio_realize_pipeline(mm_radio_t *radio);
-int _mmradio_start_pipeline(mm_radio_t *radio);
-int _mmradio_stop_pipeline(mm_radio_t *radio);
-int _mmradio_destroy_pipeline(mm_radio_t *radio);
-int _mmradio_apply_region(mm_radio_t *radio, MMRadioRegionType region, bool update);
-int _mmradio_get_region_type(mm_radio_t *radio, MMRadioRegionType *type);
-int _mmradio_get_region_frequency_range(mm_radio_t *radio, unsigned int *min_freq, unsigned int *max_freq);
-int _mmradio_get_channel_spacing(mm_radio_t *radio, unsigned int *ch_spacing);
-int _mmradio_set_volume(mm_radio_t *radio, float volume);
-int _mmradio_get_volume(mm_radio_t *radio, float *pVolume);
-
-#ifdef __cplusplus
- }
-#endif
-
-#endif /* __MM_Radio_INTERNAL_H__ */
+++ /dev/null
-/*
- * mm_radio_priv_hal.h
- *
- * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef __MM_Radio_INTERNAL_H__
-#define __MM_Radio_INTERNAL_H__
-
-/*===========================================================================================
- INCLUDE FILES
-========================================================================================== */
-#include <stdio.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <malloc.h>
-#include <pthread.h>
-#include <signal.h>
-
-#include <mm_types.h>
-#include <mm_message.h>
-#include <media/sound_manager.h>
-#include <media/sound_manager_internal.h>
-
-#include "mm_radio.h"
-#include "mm_radio_utils.h"
-#include "mm_radio_rm.h"
-#include <linux/videodev2.h>
-
-#include <glib.h>
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/*===========================================================================================
- GLOBAL DEFINITIONS AND DECLARATIONS FOR MODULE
-========================================================================================== */
-
-/*---------------------------------------------------------------------------
- GLOBAL #defines:
----------------------------------------------------------------------------*/
-#define SAMPLEDELAY 15000
-
-/* si470x dependent define */
-#define SYSCONFIG1 4 /* System Configuration 1 */
-#define SYSCONFIG1_RDS 0x1000 /* bits 12..12: RDS Enable */
-#define SYSCONFIG1_RDS_OFFSET 12 /* bits 12..12: RDS Enable Offset */
-
-#define SYSCONFIG2 5 /* System Configuration 2 */
-#define SYSCONFIG2_SEEKTH 0xff00 /* bits 15..08: RSSI Seek Threshold */
-#define SYSCONFIG2_SEEKTH_OFFSET 8 /* bits 15..08: RSSI Seek Threshold Offset */
-
-#define SYSCONFIG3 6 /* System Configuration 3 */
-#define SYSCONFIG3_SKSNR 0x00f0 /* bits 07..04: Seek SNR Threshold */
-#define SYSCONFIG3_SKCNT 0x000f /* bits 03..00: Seek FM Impulse Detection Threshold */
-#define SYSCONFIG3_SKSNR_OFFSET 4 /* bits 07..04: Seek SNR Threshold Offset */
-#define SYSCONFIG3_SKCNT_OFFSET 0 /* bits 03..00: Seek FM Impulse Detection Threshold Offset */
-
-#define DEFAULT_CHIP_MODEL "radio-si470x"
-
-/*---------------------------------------------------------------------------
- GLOBAL CONSTANT DEFINITIONS:
----------------------------------------------------------------------------*/
-typedef enum {
- MMRADIO_COMMAND_CREATE = 0,
- MMRADIO_COMMAND_DESTROY,
- MMRADIO_COMMAND_REALIZE,
- MMRADIO_COMMAND_UNREALIZE,
- MMRADIO_COMMAND_START,
- MMRADIO_COMMAND_STOP,
- MMRADIO_COMMAND_START_SCAN,
- MMRADIO_COMMAND_STOP_SCAN,
- MMRADIO_COMMAND_SET_FREQ,
- MMRADIO_COMMAND_GET_FREQ,
- MMRADIO_COMMAND_VOLUME,
- MMRADIO_COMMAND_MUTE,
- MMRADIO_COMMAND_UNMUTE,
- MMRADIO_COMMAND_SEEK,
- MMRADIO_COMMAND_SET_REGION,
- MMRADIO_COMMAND_GET_REGION,
- MMRADIO_COMMAND_SET_VOLUME,
- MMRADIO_COMMAND_GET_VOLUME,
- MMRADIO_COMMAND_NUM
-} MMRadioCommand;
-
-/* max and mix frequency types, KHz */
-typedef enum {
- MM_RADIO_FREQ_NONE = 0,
- /* min band types */
- MM_RADIO_FREQ_MIN_76100_KHZ = 76100,
- MM_RADIO_FREQ_MIN_87500_KHZ = 87500,
- MM_RADIO_FREQ_MIN_88100_KHZ = 88100,
- /* max band types */
- MM_RADIO_FREQ_MAX_89900_KHZ = 89900,
- MM_RADIO_FREQ_MAX_108000_KHZ = 108000,
-} MMRadioFreqTypes;
-
-/* de-emphasis types */
-typedef enum {
- MM_RADIO_DEEMPHASIS_NONE = 0,
- MM_RADIO_DEEMPHASIS_50_US,
- MM_RADIO_DEEMPHASIS_75_US,
-} MMRadioDeemphasis;
-
-/* radio region settings */
-typedef struct {
- MMRadioRegionType country;
- MMRadioDeemphasis deemphasis; // unit : us
- MMRadioFreqTypes band_min; // <- freq. range, unit : KHz
- MMRadioFreqTypes band_max; // ->
- int channel_spacing; // TBD
-} MMRadioRegion_t;
-
-typedef struct {
- pthread_t thread;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- int thread_id;
- bool is_running;
- bool stop;
- bool thread_exit;
-} MMRadioThread_t;
-
-typedef enum {
- MM_RADIO_MSG_DESTROY = 0,
- MM_RADIO_MSG_SCAN_INFO,
- MM_RADIO_MSG_SCAN_STOPPED,
- MM_RADIO_MSG_SCAN_FINISHED,
- MM_RADIO_MSG_SEEK_FINISHED,
- MM_RADIO_MSG_STATE_INTERRUPTED,
- MM_RADIO_MSG_NUM
-} MMRadioMsgTypes;
-
-typedef struct {
- bool destroy;
- MMRadioMsgTypes msg_type;
- int data;
-} mm_radio_msg_t;
-
-typedef enum {
- MM_RADIO_THREAD_MSG = 0,
- MM_RADIO_THREAD_SEEK,
- MM_RADIO_THREAD_SCAN,
- MM_RADIO_THREAD_NUM
-} MMRadioThreadTypes;
-
-/*---------------------------------------------------------------------------
- GLOBAL DATA TYPE DEFINITIONS:
----------------------------------------------------------------------------*/
-
-typedef struct {
- /* radio state */
- int current_state;
- int old_state;
- int pending_state;
-
- int cmd;
-
- /* command lock */
- pthread_mutex_t cmd_lock;
-
- /* radio attributes */
- MMHandleType *attrs;
-
- MMRadioThread_t thread[MM_RADIO_THREAD_NUM];
-
- /* message callback */
- GAsyncQueue *msg_queue;
- MMMessageCallback msg_cb;
- void *msg_cb_param;
-
- /* seek */
- int prev_seek_freq;
- bool is_muted;
- bool seek_unmute;
- bool is_ready;
-
- pthread_mutex_t hal_seek_mutex;
-
- MMRadioSeekDirectionType seek_direction;
-
- sound_stream_info_h stream_info;
- virtual_sound_stream_h vstream;
-
- int freq;
-
- float local_volume;
-
- /* region settings */
- MMRadioRegion_t region_setting;
-
- void *hal_radio;
-
- radio_resource_s resource;
-
- int interrupted_by_resource_conflict;
-
-} mm_radio_t;
-
-/*===========================================================================================
- GLOBAL FUNCTION PROTOTYPES
-========================================================================================== */
-int _mmradio_create_radio(mm_radio_t *radio);
-int _mmradio_destroy(mm_radio_t *radio);
-int _mmradio_realize(mm_radio_t *radio);
-int _mmradio_unrealize(mm_radio_t *radio);
-int _mmradio_set_message_callback(mm_radio_t *radio, MMMessageCallback callback, void *user_param);
-int _mmradio_get_state(mm_radio_t *radio, int *pState);
-int _mmradio_set_frequency(mm_radio_t *radio, int freq);
-int _mmradio_get_frequency(mm_radio_t *radio, int *pFreq);
-int _mmradio_mute(mm_radio_t *radio);
-int _mmradio_unmute(mm_radio_t *radio);
-int _mmradio_start(mm_radio_t *radio);
-int _mmradio_stop(mm_radio_t *radio);
-int _mmradio_seek(mm_radio_t *radio, MMRadioSeekDirectionType direction);
-int _mmradio_start_scan(mm_radio_t *radio);
-int _mmradio_stop_scan(mm_radio_t *radio);
-int _mmradio_get_signal_strength(mm_radio_t *radio, int *value);
-int _mmradio_apply_region(mm_radio_t*radio, MMRadioRegionType region, bool update);
-int _mmradio_get_region_type(mm_radio_t*radio, MMRadioRegionType *type);
-int _mmradio_get_region_frequency_range(mm_radio_t *radio, unsigned int *min_freq, unsigned int *max_freq);
-int _mmradio_get_channel_spacing(mm_radio_t* radio, unsigned int *ch_spacing);
-int _mmradio_set_volume(mm_radio_t *radio, float volume);
-int _mmradio_get_volume(mm_radio_t *radio, float *pVolume);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __MM_Radio_INTERNAL_H__ */
#define MMRADIO_CHECK_DEVICE_STATE(x_radio) \
do { \
- if (x_radio->radio_fd < 0) { \
+ if ((!x_radio->is_ready)) { \
MMRADIO_LOG_ERROR("not available radio device\n"); \
return MM_ERROR_RADIO_NOT_INITIALIZED; \
} \
#define MMRADIO_THREAD_SIGNAL(x_thread_t) pthread_cond_signal(&x_thread_t->cond)
/* hal seek thread */
-#define MMRADIO_HAL_SEEK_THREAD_LOCK(x_radio) pthread_mutex_lock(&((mm_radio_t *)x_radio)->hal_seek_mutex)
-#define MMRADIO_HAL_SEEK_THREAD_UNLOCK(x_radio) pthread_mutex_unlock(&((mm_radio_t *)x_radio)->hal_seek_mutex)
+#define MMRADIO_SEEK_THREAD_LOCK(x_radio) pthread_mutex_lock(&((mm_radio_t *)x_radio)->seek_mutex)
+#define MMRADIO_SEEK_THREAD_UNLOCK(x_radio) pthread_mutex_unlock(&((mm_radio_t *)x_radio)->seek_mutex)
/* message posting */
#define MMRADIO_POST_MSG(x_radio, x_msgtype, x_msg_param) \
do { \
MMRADIO_LOG_DEBUG("posting %s to application\n", #x_msgtype); \
- __mmradio_post_message(x_radio, x_msgtype, x_msg_param); \
+ _mmradio_common_post_message(x_radio, x_msgtype, x_msg_param); \
} while (0)
/* setting radio state */
#define MMRADIO_SET_STATE(x_radio, x_state) \
do { \
MMRADIO_LOG_DEBUG("setting mm-radio state to %d\n", x_state); \
- __mmradio_set_state(x_radio, x_state); \
+ _mmradio_common_set_state(x_radio, x_state); \
} while (0)
/* state */
#define MMRADIO_CHECK_STATE_RETURN_IF_FAIL(x_radio, x_command) \
do { \
MMRADIO_LOG_DEBUG("checking radio state before doing %s\n", #x_command); \
- switch (__mmradio_check_state(x_radio, x_command)) { \
+ switch (_mmradio_common_check_state(x_radio, x_command)) { \
case MM_ERROR_RADIO_INVALID_STATE: \
return MM_ERROR_RADIO_INVALID_STATE; \
break; \
} while (0)
#endif
-
#include <mm_types.h>
#include <mm_message.h>
#include "mm_radio.h"
-#ifdef TIZEN_FEATURE_RADIO_HAL
-#include "mm_radio_priv_hal.h"
-#else
-#include "mm_radio_priv_emul.h"
-#endif
+#include "mm_radio_priv.h"
#include "mm_radio_utils.h"
/*===========================================================================================
--- /dev/null
+/*
+ * mm_radio_priv_common.c
+ *
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "mm_radio_priv.h"
+
+static void __mmradio_destroy_thread_type(mm_radio_t *radio, MMRadioThreadTypes type);
+static int __mmradio_get_state(mm_radio_t *radio);
+
+static const MMRadioRegion_t region_table[] = {
+ { /* North America, South America, South Korea, Taiwan, Australia */
+ MM_RADIO_REGION_GROUP_USA, /* region type */
+ MM_RADIO_DEEMPHASIS_75_US, /* de-emphasis */
+ MM_RADIO_FREQ_MIN_87500_KHZ, /* min freq. */
+ MM_RADIO_FREQ_MAX_108000_KHZ, /* max freq. */
+ 50,
+ },
+ { /* China, Europe, Africa, Middle East, Hong Kong, India, Indonesia, Russia, Singapore */
+ MM_RADIO_REGION_GROUP_EUROPE,
+ MM_RADIO_DEEMPHASIS_50_US,
+ MM_RADIO_FREQ_MIN_87500_KHZ,
+ MM_RADIO_FREQ_MAX_108000_KHZ,
+ 50,
+ },
+ {
+ MM_RADIO_REGION_GROUP_JAPAN,
+ MM_RADIO_DEEMPHASIS_50_US,
+ MM_RADIO_FREQ_MIN_76100_KHZ,
+ MM_RADIO_FREQ_MAX_89900_KHZ,
+ 50,
+ },
+};
+
+int _mmradio_apply_region(mm_radio_t *radio, MMRadioRegionType region, bool update)
+{
+ int ret = MM_ERROR_NONE;
+ int count = 0;
+ int index = 0;
+
+ MMRADIO_LOG_FENTER();
+
+ MMRADIO_CHECK_INSTANCE(radio);
+ MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_REGION);
+
+ /* if needed, radio region must be updated.
+ * Otherwise, just applying settings to device without it.
+ */
+ if (update) {
+ count = ARRAY_SIZE(region_table);
+
+ /* TODO: if auto is supported...get the region info. here */
+
+ /* update radio region settings */
+ for (index = 0; index < count; index++) {
+ /* find the region from pre-defined table */
+ if (region_table[index].country == region) {
+ radio->region_setting.country = region_table[index].country;
+ radio->region_setting.deemphasis = region_table[index].deemphasis;
+ radio->region_setting.band_min = region_table[index].band_min;
+ radio->region_setting.band_max = region_table[index].band_max;
+ radio->region_setting.channel_spacing = region_table[index].channel_spacing;
+ }
+ }
+ }
+
+ MMRADIO_LOG_INFO("setting region - country: %d, de-emphasis: %d, band range: %d ~ %d KHz",
+ radio->region_setting.country, radio->region_setting.deemphasis,
+ radio->region_setting.band_min, radio->region_setting.band_max);
+
+ MMRADIO_LOG_FLEAVE();
+
+ return ret;
+}
+
+int _mmradio_set_message_callback(mm_radio_t *radio, MMMessageCallback callback, void *user_param)
+{
+ MMRADIO_LOG_FENTER();
+
+ MMRADIO_CHECK_INSTANCE(radio);
+
+ radio->msg_cb = callback;
+ radio->msg_cb_param = user_param;
+
+ MMRADIO_LOG_DEBUG("msg_cb : %p msg_cb_param : %p", callback, user_param);
+
+ MMRADIO_LOG_FLEAVE();
+
+ return MM_ERROR_NONE;
+}
+
+int _mmradio_get_state(mm_radio_t *radio, int *pState)
+{
+ int state = 0;
+
+ MMRADIO_LOG_FENTER();
+
+ MMRADIO_CHECK_INSTANCE(radio);
+ MMRADIO_RETURN_VAL_IF_FAIL(pState, MM_ERROR_INVALID_ARGUMENT);
+
+ state = __mmradio_get_state(radio);
+
+ *pState = state;
+
+ MMRADIO_LOG_FLEAVE();
+
+ return MM_ERROR_NONE;
+}
+
+int _mmradio_stop_scan(mm_radio_t *radio)
+{
+ MMRADIO_LOG_FENTER();
+
+ MMRADIO_CHECK_INSTANCE(radio);
+ MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_STOP_SCAN);
+
+ radio->thread[MM_RADIO_THREAD_SCAN].stop = true;
+
+ MMRADIO_LOG_FLEAVE();
+
+ return MM_ERROR_NONE;
+}
+
+bool _mmradio_common_is_tunable_frequency(mm_radio_t *radio, int freq)
+{
+ MMRADIO_LOG_FENTER();
+
+ MMRADIO_CHECK_INSTANCE(radio);
+
+ if (freq >= radio->region_setting.band_max
+ || freq <= radio->region_setting.band_min)
+ return false;
+
+ MMRADIO_LOG_FLEAVE();
+
+ return true;
+}
+
+bool _mmradio_common_post_message(mm_radio_t *radio, enum MMMessageType msgtype, MMMessageParamType *param)
+{
+ MMRADIO_CHECK_INSTANCE(radio);
+
+ MMRADIO_LOG_FENTER();
+
+ if (!radio->msg_cb) {
+ MMRADIO_LOG_WARNING("failed to post a message because msg cb didn't register");
+ return false;
+ }
+
+ MMRADIO_LOG_DEBUG("address of msg_cb : %p", radio->msg_cb);
+
+ radio->msg_cb(msgtype, param, radio->msg_cb_param);
+
+ MMRADIO_LOG_FLEAVE();
+
+ return true;
+}
+
+int _mmradio_common_check_state(mm_radio_t *radio, MMRadioCommand command)
+{
+ MMRadioStateType radio_state = MM_RADIO_STATE_NUM;
+
+ MMRADIO_LOG_FENTER();
+
+ MMRADIO_CHECK_INSTANCE(radio);
+
+ radio_state = __mmradio_get_state(radio);
+
+ MMRADIO_LOG_INFO("incoming command : %d current state : %d", command, radio_state);
+
+ switch (command) {
+ case MMRADIO_COMMAND_CREATE:
+ if (radio_state != 0)
+ goto NO_OP;
+
+ break;
+ case MMRADIO_COMMAND_REALIZE:
+ if (radio_state == MM_RADIO_STATE_READY ||
+ radio_state == MM_RADIO_STATE_PLAYING ||
+ radio_state == MM_RADIO_STATE_SCANNING)
+ goto NO_OP;
+
+ if (radio_state == 0)
+ goto INVALID_STATE;
+ break;
+ case MMRADIO_COMMAND_UNREALIZE:
+ if (radio_state == MM_RADIO_STATE_NULL)
+ goto NO_OP;
+ /* we can call unrealize at any higher state */
+ break;
+ case MMRADIO_COMMAND_START:
+ if (radio_state == MM_RADIO_STATE_PLAYING)
+ goto NO_OP;
+
+ if (radio_state != MM_RADIO_STATE_READY)
+ goto INVALID_STATE;
+
+ break;
+ case MMRADIO_COMMAND_STOP:
+ if (radio_state == MM_RADIO_STATE_READY)
+ goto NO_OP;
+
+ if (radio_state != MM_RADIO_STATE_PLAYING)
+ goto INVALID_STATE;
+
+ break;
+ case MMRADIO_COMMAND_START_SCAN:
+ if (radio_state == MM_RADIO_STATE_SCANNING)
+ goto NO_OP;
+
+ if (radio_state == MM_RADIO_STATE_NULL)
+ goto INVALID_STATE;
+
+ break;
+ case MMRADIO_COMMAND_STOP_SCAN:
+ if (radio_state == MM_RADIO_STATE_READY)
+ goto NO_OP;
+
+ if (radio_state != MM_RADIO_STATE_SCANNING)
+ goto INVALID_STATE;
+
+ break;
+ case MMRADIO_COMMAND_DESTROY:
+ case MMRADIO_COMMAND_MUTE:
+ case MMRADIO_COMMAND_UNMUTE:
+ case MMRADIO_COMMAND_SET_FREQ:
+ case MMRADIO_COMMAND_GET_FREQ:
+ case MMRADIO_COMMAND_SET_REGION:
+ case MMRADIO_COMMAND_SET_VOLUME:
+ case MMRADIO_COMMAND_GET_VOLUME:
+ break;
+ case MMRADIO_COMMAND_SEEK:
+ if (radio_state != MM_RADIO_STATE_PLAYING)
+ goto INVALID_STATE;
+
+ break;
+ case MMRADIO_COMMAND_GET_REGION:
+ if (radio_state == MM_RADIO_STATE_NULL)
+ goto INVALID_STATE;
+
+ break;
+ default:
+ MMRADIO_LOG_DEBUG("not handled in FSM. don't care it");
+ break;
+ }
+
+ MMRADIO_LOG_DEBUG("status OK");
+
+ radio->cmd = command;
+
+ MMRADIO_LOG_FLEAVE();
+
+ return MM_ERROR_NONE;
+
+INVALID_STATE:
+ MMRADIO_LOG_WARNING("invalid state. current : %d command : %d", radio_state, command);
+ MMRADIO_LOG_FLEAVE();
+ return MM_ERROR_RADIO_INVALID_STATE;
+
+NO_OP:
+ MMRADIO_LOG_WARNING("mm-radio is in the desired state(%d). doing noting", radio_state);
+ MMRADIO_LOG_FLEAVE();
+ return MM_ERROR_RADIO_NO_OP;
+
+}
+
+bool _mmradio_common_set_state(mm_radio_t *radio, int new_state)
+{
+ MMMessageParamType msg = { 0, };
+ int msg_type = MM_MESSAGE_UNKNOWN;
+
+ MMRADIO_LOG_FENTER();
+
+ if (!radio) {
+ MMRADIO_LOG_WARNING("calling set_state with invalid radio handle");
+ return false;
+ }
+
+ if (radio->current_state == new_state && radio->pending_state == 0) {
+ MMRADIO_LOG_WARNING("we are in same state");
+ return true;
+ }
+
+ /* set state */
+ radio->old_state = radio->current_state;
+ radio->current_state = new_state;
+
+ /* fill message param */
+ msg.union_type = MM_MSG_UNION_STATE;
+ msg.state.previous = radio->old_state;
+ msg.state.current = radio->current_state;
+
+ if (radio->interrupted_by_resource_conflict) {
+ _mmradio_common_msg_push(radio, MM_RADIO_MSG_STATE_INTERRUPTED,
+ MM_MSG_CODE_INTERRUPTED_BY_RESOURCE_CONFLICT);
+ } else {
+ msg_type = MM_MESSAGE_STATE_CHANGED;
+ MMRADIO_POST_MSG(radio, msg_type, &msg);
+ }
+
+ MMRADIO_LOG_FLEAVE();
+
+ return true;
+}
+
+static int __mmradio_get_state(mm_radio_t *radio)
+{
+ MMRADIO_CHECK_INSTANCE(radio);
+
+ MMRADIO_LOG_INFO("radio state : current : [%d] old : [%d] pending : [%d]",
+ radio->current_state, radio->old_state, radio->pending_state);
+
+ return radio->current_state;
+}
+
+int _mmradio_get_region_type(mm_radio_t *radio, MMRadioRegionType *type)
+{
+ MMRADIO_LOG_FENTER();
+ MMRADIO_CHECK_INSTANCE(radio);
+ MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
+
+ MMRADIO_RETURN_VAL_IF_FAIL(type, MM_ERROR_INVALID_ARGUMENT);
+
+ *type = radio->region_setting.country;
+
+ MMRADIO_LOG_FLEAVE();
+ return MM_ERROR_NONE;
+}
+
+int _mmradio_get_region_frequency_range(mm_radio_t *radio, unsigned int *min_freq, unsigned int *max_freq)
+{
+ MMRADIO_LOG_FENTER();
+ MMRADIO_CHECK_INSTANCE(radio);
+ MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
+
+ MMRADIO_RETURN_VAL_IF_FAIL(min_freq && max_freq, MM_ERROR_INVALID_ARGUMENT);
+
+ *min_freq = radio->region_setting.band_min;
+ *max_freq = radio->region_setting.band_max;
+
+ MMRADIO_LOG_FLEAVE();
+ return MM_ERROR_NONE;
+}
+
+int _mmradio_get_channel_spacing(mm_radio_t *radio, unsigned int *ch_spacing)
+{
+ MMRADIO_LOG_FENTER();
+ MMRADIO_CHECK_INSTANCE(radio);
+ MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
+
+ MMRADIO_RETURN_VAL_IF_FAIL(ch_spacing, MM_ERROR_INVALID_ARGUMENT);
+
+ *ch_spacing = radio->region_setting.channel_spacing;
+
+ MMRADIO_LOG_FLEAVE();
+ return MM_ERROR_NONE;
+}
+
+int _mmradio_get_volume(mm_radio_t *radio, float *pVolume)
+{
+ int ret = MM_ERROR_NONE;
+
+ MMRADIO_LOG_FENTER();
+
+ MMRADIO_CHECK_INSTANCE(radio);
+ MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_VOLUME);
+
+ MMRADIO_RETURN_VAL_IF_FAIL(pVolume, MM_ERROR_INVALID_ARGUMENT);
+
+ *pVolume = radio->local_volume;
+
+ MMRADIO_LOG_FLEAVE();
+
+ return ret;
+}
+
+static int __mmradio_create_thread_type(mm_radio_t *radio, MMRadioThreadTypes type, void **function)
+{
+ MMRadioThread_t *p_thread = NULL;
+
+ MMRADIO_LOG_FENTER();
+
+ MMRADIO_CHECK_INSTANCE(radio);
+ MMRADIO_CHECK_INSTANCE(function);
+ if (type >= MM_RADIO_THREAD_NUM) {
+ MMRADIO_LOG_WARNING("wrong argument thread type");
+ return MM_ERROR_RADIO_INTERNAL;
+ }
+ MMRADIO_CHECK_INSTANCE(function[type]);
+
+ p_thread = &radio->thread[type];
+ p_thread->is_running = false;
+ MMRADIO_CHECK_ARG(p_thread);
+
+ MMRADIO_INIT_MUTEX(p_thread->mutex);
+ MMRADIO_INIT_COND(p_thread->cond);
+
+ p_thread->thread_id = pthread_create(&p_thread->thread, NULL,
+ (void *)function[type], (void *)radio);
+ if (p_thread->thread_id) {
+ MMRADIO_LOG_DEBUG("failed to create thread : [%d]", type);
+ return MM_ERROR_RADIO_INTERNAL;
+ }
+
+ return MM_ERROR_NONE;
+
+ERROR:
+ pthread_mutex_destroy(&p_thread->mutex);
+ pthread_cond_destroy(&p_thread->cond);
+ return MM_ERROR_RADIO_INTERNAL;
+
+}
+
+int _mmradio_common_create_threads(mm_radio_t *radio, void **function)
+{
+ int ret = MM_ERROR_NONE;
+ int type = 0;
+
+ MMRADIO_LOG_FENTER();
+
+ MMRADIO_CHECK_INSTANCE(radio);
+ MMRADIO_CHECK_INSTANCE(function);
+
+ MMRADIO_INIT_MUTEX(radio->cmd_lock);
+ MMRADIO_INIT_MUTEX(radio->seek_mutex);
+
+ for (type = (int)MM_RADIO_THREAD_MSG; type < (int)MM_RADIO_THREAD_NUM; type++) {
+ ret = __mmradio_create_thread_type(radio, (MMRadioThreadTypes)type, function);
+ if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("failed to create thread(%d)", type);
+ while (--type >= (int)MM_RADIO_THREAD_MSG)
+ __mmradio_destroy_thread_type(radio, (MMRadioThreadTypes)type);
+ goto ERROR;
+ }
+ }
+
+ MMRADIO_LOG_FLEAVE();
+ return ret;
+
+ERROR:
+ pthread_mutex_destroy(&radio->cmd_lock);
+ pthread_mutex_destroy(&radio->seek_mutex);
+
+ MMRADIO_LOG_FLEAVE();
+ return MM_ERROR_RADIO_INTERNAL;
+}
+
+static void __mmradio_destroy_thread_type(mm_radio_t *radio, MMRadioThreadTypes type)
+{
+ MMRadioThread_t *p_thread = NULL;
+ mm_radio_msg_t *msg = NULL;
+ MMRADIO_LOG_FENTER();
+
+ MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
+
+ if (type >= MM_RADIO_THREAD_NUM) {
+ MMRADIO_LOG_WARNING("wrong argument thread type");
+ return;
+ }
+
+ p_thread = &radio->thread[type];
+ MMRADIO_CHECK_ARG_RETURN_VOID(p_thread);
+
+ if (p_thread->thread) {
+ if (type == MM_RADIO_THREAD_MSG) {
+ msg = g_slice_new0(mm_radio_msg_t);
+ msg->msg_type = MM_RADIO_MSG_DESTROY;
+ g_async_queue_push_front(radio->msg_queue, msg);
+ } else {
+ MMRADIO_THREAD_LOCK(p_thread);
+ p_thread->thread_exit = true;
+ p_thread->is_running = true;
+ MMRADIO_THREAD_SIGNAL(p_thread);
+ MMRADIO_THREAD_UNLOCK(p_thread);
+ }
+ pthread_join(p_thread->thread, NULL);
+ p_thread->thread = 0;
+ } else {
+ MMRADIO_LOG_WARNING("(%d)thread is zero", type);
+ }
+
+ pthread_mutex_destroy(&p_thread->mutex);
+ pthread_cond_destroy(&p_thread->cond);
+
+ MMRADIO_LOG_FLEAVE();
+}
+
+void _mmradio_common_destroy_threads(mm_radio_t *radio)
+{
+ int type;
+ MMRADIO_LOG_FENTER();
+
+ MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
+
+ for (type = MM_RADIO_THREAD_SCAN; type >= MM_RADIO_THREAD_MSG; type--)
+ __mmradio_destroy_thread_type(radio, (MMRadioThreadTypes)type);
+
+ pthread_mutex_destroy(&radio->cmd_lock);
+ pthread_mutex_destroy(&radio->seek_mutex);
+
+ MMRADIO_LOG_FLEAVE();
+}
+
+void _mmradio_common_msg_push(mm_radio_t *radio, MMRadioMsgTypes msg_type, int msg_data)
+{
+ mm_radio_msg_t *msg = g_slice_new0(mm_radio_msg_t);
+
+ msg->msg_type = msg_type;
+ msg->data = msg_data;
+
+ MMRADIO_LOG_INFO("push msg_type: %d, msg_data: %d", (int)msg->msg_type, msg->data);
+ g_async_queue_push(radio->msg_queue, msg);
+}
*
*/
-/*===========================================================================================
-| |
-| INCLUDE FILES |
-| |
-========================================================================================== */
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <mm_error.h>
-#include <mm_message.h>
-#include <time.h>
-
-#include "mm_radio_priv_emul.h"
-
-/*===========================================================================================
- LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE
-========================================================================================== */
-/*---------------------------------------------------------------------------
- GLOBAL CONSTANT DEFINITIONS:
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
- IMPORTED VARIABLE DECLARATIONS:
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
- IMPORTED FUNCTION DECLARATIONS:
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
- LOCAL #defines:
----------------------------------------------------------------------------*/
-#define TUNER_INDEX 0
-
-#define DEFAULT_FREQ 107700
-
-#define FREQ_FRAC 16
-#define RADIO_FREQ_FORMAT_SET(x_freq) ((x_freq) * FREQ_FRAC)
-#define RADIO_FREQ_FORMAT_GET(x_freq) ((x_freq) / FREQ_FRAC)
-/* If non-zero, wrap around when at the end of the frequency range, else stop seeking */
-#define DEFAULT_WRAP_AROUND 1
-
-#define RADIO_DEFAULT_REGION MM_RADIO_REGION_GROUP_USA
+#include "mm_radio_priv.h"
+
#define EMULATOR_FREQ_MAX 5
#define RADIO_MIN_VOLUME 0.0
#define RADIO_MAX_VOLUME 1.0
#define RADIO_GST_STATE_CHANGE_TIMEOUT (10 * GST_SECOND)
-/*---------------------------------------------------------------------------
- LOCAL CONSTANT DEFINITIONS:
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
- LOCAL DATA TYPE DEFINITIONS:
----------------------------------------------------------------------------*/
-/*---------------------------------------------------------------------------
- GLOBAL VARIABLE DEFINITIONS:
----------------------------------------------------------------------------*/
extern int errno;
-/*---------------------------------------------------------------------------
- LOCAL VARIABLE DEFINITIONS:
----------------------------------------------------------------------------*/
-/* radio region configuration table */
-static const MMRadioRegion_t region_table[] = {
- { /* North America, South America, South Korea, Taiwan, Australia */
- MM_RADIO_REGION_GROUP_USA, /* region type */
- MM_RADIO_DEEMPHASIS_75_US, /* de-emphasis */
- MM_RADIO_FREQ_MIN_87500_KHZ, /* min freq. */
- MM_RADIO_FREQ_MAX_108000_KHZ, /* max freq. */
- 50,
- },
- { /* China, Europe, Africa, Middle East, Hong Kong, India, Indonesia, Russia, Singapore */
- MM_RADIO_REGION_GROUP_EUROPE,
- MM_RADIO_DEEMPHASIS_50_US,
- MM_RADIO_FREQ_MIN_87500_KHZ,
- MM_RADIO_FREQ_MAX_108000_KHZ,
- 50,
- },
- {
- MM_RADIO_REGION_GROUP_JAPAN,
- MM_RADIO_DEEMPHASIS_50_US,
- MM_RADIO_FREQ_MIN_76100_KHZ,
- MM_RADIO_FREQ_MAX_89900_KHZ,
- 50,
- },
-};
-
static int MMRadioEmulatorFreq[EMULATOR_FREQ_MAX] = {
89100, 89900, 91900, 99900, 107700
};
-/*---------------------------------------------------------------------------
- LOCAL FUNCTION PROTOTYPES:
----------------------------------------------------------------------------*/
-static bool __mmradio_post_message(mm_radio_t * radio, enum MMMessageType msgtype, MMMessageParamType * param);
-static int __mmradio_check_state(mm_radio_t * radio, MMRadioCommand command);
-static int __mmradio_get_state(mm_radio_t * radio);
-static bool __mmradio_set_state(mm_radio_t * radio, int new_state);
static void __mmradio_seek_thread(mm_radio_t * radio);
static void __mmradio_scan_thread(mm_radio_t * radio);
-static bool __is_tunable_frequency(mm_radio_t * radio, int freq);
-static int __mmradio_create_threads(mm_radio_t *radio);
-static void __mmradio_destroy_threads(mm_radio_t *radio);
-static int __mmradio_create_thread_type(mm_radio_t *radio, MMRadioThreadTypes type);
-static void __mmradio_destroy_thread_type(mm_radio_t *radio, MMRadioThreadTypes type);
-static int __mmradio_set_deemphasis(mm_radio_t * radio);
-static int __mmradio_set_band_range(mm_radio_t * radio);
static int __mmradio_get_wave_num(mm_radio_t * radio);
static void __mmradio_msg_thread(mm_radio_t *radio);
-static void __mmradio_msg_push(mm_radio_t *radio, MMRadioMsgTypes msg_type, int msg_data);
+static int __mmradio_realize_pipeline(mm_radio_t *radio);
+static int __mmradio_start_pipeline(mm_radio_t *radio);
+static int __mmradio_stop_pipeline(mm_radio_t *radio);
+static int __mmradio_destroy_pipeline(mm_radio_t *radio);
typedef void (*thread_function)(mm_radio_t *);
thread_function __mmradio_thread_function[] = {
&__mmradio_scan_thread
};
-/*===========================================================================
- FUNCTION DEFINITIONS
-========================================================================== */
-/* --------------------------------------------------------------------------
- * Name : _mmradio_apply_region()
- * Desc : update radio region information and set values to device
- * Param :
- * [in] radio : radio handle
- * [in] region : region type
- * [in] update : update region values or not
- * Return : zero on success, or negative value with error code
- *---------------------------------------------------------------------------*/
-int _mmradio_apply_region(mm_radio_t * radio, MMRadioRegionType region, bool update)
-{
- int ret = MM_ERROR_NONE;
- int count = 0;
- int index = 0;
-
- MMRADIO_LOG_FENTER();
-
- MMRADIO_CHECK_INSTANCE(radio);
- MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_REGION);
-
- /* if needed, radio region must be updated.
- * Otherwise, just applying settings to device without it.
- */
- if (update) {
- count = ARRAY_SIZE(region_table);
-
- /* TODO: if auto is supported...get the region info. here */
-
- /* update radio region settings */
- for (index = 0; index < count; index++) {
- /* find the region from pre-defined table */
- if (region_table[index].country == region) {
- radio->region_setting.country = region_table[index].country;
- radio->region_setting.deemphasis = region_table[index].deemphasis;
- radio->region_setting.band_min = region_table[index].band_min;
- radio->region_setting.band_max = region_table[index].band_max;
- radio->region_setting.channel_spacing = region_table[index].channel_spacing;
- }
- }
- }
-
- /* check device is opened or not. if it's not ready, skip to apply region to device now */
- if (radio->radio_fd < 0) {
- MMRADIO_LOG_DEBUG("not opened device. just updating region info.");
- return MM_ERROR_NONE;
- }
-
- MMRADIO_SLOG_DEBUG("setting region - country: %d, de-emphasis: %d, band range: %d ~ %d KHz\n",
- radio->region_setting.country, radio->region_setting.deemphasis,
- radio->region_setting.band_min, radio->region_setting.band_max);
-
- /* set de-emphasis to device */
- ret = __mmradio_set_deemphasis(radio);
-
- MMRADIO_CHECK_RETURN_IF_FAIL(ret, "set de-emphasis");
-
- /* set band range to device */
- ret = __mmradio_set_band_range(radio);
-
- MMRADIO_CHECK_RETURN_IF_FAIL(ret, "set band range");
-
- MMRADIO_LOG_FLEAVE();
-
- return ret;
-}
-
int _mmradio_create_radio(mm_radio_t * radio)
{
int ret = MM_ERROR_NONE;
MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_CREATE);
/* set default value */
- radio->radio_fd = -1;
+ radio->is_ready = false;
radio->freq = DEFAULT_FREQ;
memset(&radio->region_setting, 0, sizeof(MMRadioRegion_t));
radio->local_volume = 1.0;
}
/* create mutex and thread */
- ret = __mmradio_create_threads(radio);
+ ret = _mmradio_common_create_threads(radio, (void **)__mmradio_thread_function);
if (ret) {
MMRADIO_LOG_ERROR("failed to create threads");
goto ERROR_THREAD;
return MM_ERROR_NONE;
ERROR_RESOURCE:
- __mmradio_destroy_threads(radio);
+ _mmradio_common_destroy_threads(radio);
ERROR_THREAD:
if (radio->msg_queue)
g_async_queue_unref(radio->msg_queue);
MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_REALIZE);
/* open radio device */
- if (radio->radio_fd == -1) {
+ if (!radio->is_ready) {
MMRadioRegionType region = MM_RADIO_REGION_GROUP_NONE;
bool update = false;
/* open device */
- radio->radio_fd = 11;
+ radio->is_ready = true;
- MMRADIO_LOG_DEBUG("radio device fd : %d", radio->radio_fd);
+ MMRADIO_LOG_DEBUG("radio device fd : %d", radio->is_ready);
/* check region country type if it's updated or not */
if (radio->region_setting.country == MM_RADIO_REGION_GROUP_NONE) {
MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
- ret = _mmradio_realize_pipeline(radio);
+ ret = __mmradio_realize_pipeline(radio);
if (ret) {
MMRADIO_LOG_ERROR("failed to realize pipeline");
return ret;
MMRADIO_LOG_WARNING("failed to stop radio");
/* close radio device here !!!! */
- if (radio->radio_fd >= 0)
- radio->radio_fd = -1;
+ if (radio->is_ready)
+ radio->is_ready = false;
MMRADIO_SET_STATE(radio, MM_RADIO_STATE_NULL);
- ret = _mmradio_destroy_pipeline(radio);
+ ret = __mmradio_destroy_pipeline(radio);
if (ret) {
MMRADIO_LOG_ERROR("failed to destroy pipeline");
return ret;
_mmradio_unrealize(radio);
/* destroy mutex and thread */
- __mmradio_destroy_threads(radio);
+ _mmradio_common_destroy_threads(radio);
if (radio->msg_queue)
g_async_queue_unref(radio->msg_queue);
MMRADIO_SLOG_DEBUG("Setting %d frequency", freq);
MMRADIO_LOG_DEBUG("radio->freq: %d freq: %d", radio->freq, freq);
- if (radio->radio_fd < 0) {
+ if (!radio->is_ready) {
MMRADIO_LOG_DEBUG("radio device is not opened yet");
return MM_ERROR_NONE;
}
MMRADIO_RETURN_VAL_IF_FAIL(pFreq, MM_ERROR_INVALID_ARGUMENT);
/* just return stored frequency if radio device is not ready */
- if (radio->radio_fd < 0) {
+ if (!radio->is_ready) {
MMRADIO_SLOG_DEBUG("freq : %d", radio->freq);
*pFreq = radio->freq;
return MM_ERROR_NONE;
MMRADIO_CHECK_INSTANCE(radio);
MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_MUTE);
-
- if (radio->radio_fd < 0)
- return MM_ERROR_RADIO_NOT_INITIALIZED;
+ MMRADIO_CHECK_DEVICE_STATE(radio);
if (radio->pipeline && radio->pipeline->volume) {
g_object_set(radio->pipeline->volume, "mute", 1, NULL);
return MM_ERROR_NONE;
}
-/* --------------------------------------------------------------------------
- * Name : __mmradio_set_deemphasis
- * Desc : apply de-emphasis value to device
- * Param :
- * [in] radio : radio handle
- * Return : zero on success, or negative value with error code
- *---------------------------------------------------------------------------*/
-int __mmradio_set_deemphasis(mm_radio_t * radio)
-{
- int value = 0;
-
- MMRADIO_LOG_FENTER();
- return MM_ERROR_NONE;
- MMRADIO_CHECK_INSTANCE(radio);
-
- /* get de-emphasis */
- switch (radio->region_setting.deemphasis) {
- case MM_RADIO_DEEMPHASIS_50_US:
- /* V4L2_DEEMPHASIS_50_uS; */
- value = 1;
- break;
-
- case MM_RADIO_DEEMPHASIS_75_US:
- /* V4L2_DEEMPHASIS_75_uS; */
- value = 2;
- break;
-
- default:
- MMRADIO_LOG_ERROR("not available de-emphasis value");
- return MM_ERROR_COMMON_INVALID_ARGUMENT;
- }
-
- MMRADIO_LOG_DEBUG("set deemphasis %d", value);
-
- MMRADIO_LOG_FLEAVE();
-
- return MM_ERROR_NONE;
-}
-
-/* --------------------------------------------------------------------------
- * Name : __mmradio_set_band_range
- * Desc : apply max and min frequency to device
- * Param :
- * [in] radio : radio handle
- * Return : zero on success, or negative value with error code
- *---------------------------------------------------------------------------*/
-int __mmradio_set_band_range(mm_radio_t * radio)
-{
- MMRADIO_LOG_FENTER();
- return MM_ERROR_NONE;
- MMRADIO_CHECK_INSTANCE(radio);
-
- MMRADIO_LOG_FLEAVE();
-
- return MM_ERROR_NONE;
-}
-
-int _mmradio_set_message_callback(mm_radio_t * radio, MMMessageCallback callback, void *user_param)
-{
- MMRADIO_LOG_FENTER();
-
- MMRADIO_CHECK_INSTANCE(radio);
-
- radio->msg_cb = callback;
- radio->msg_cb_param = user_param;
-
- MMRADIO_LOG_DEBUG("msg_cb : %p msg_cb_param : %p", callback, user_param);
-
- MMRADIO_LOG_FLEAVE();
-
- return MM_ERROR_NONE;
-}
-
-int _mmradio_get_state(mm_radio_t * radio, int *pState)
-{
- int state = 0;
-
- MMRADIO_LOG_FENTER();
-
- MMRADIO_CHECK_INSTANCE(radio);
- MMRADIO_RETURN_VAL_IF_FAIL(pState, MM_ERROR_INVALID_ARGUMENT);
-
- state = __mmradio_get_state(radio);
-
- *pState = state;
-
- MMRADIO_LOG_FLEAVE();
-
- return MM_ERROR_NONE;
-}
-
int _mmradio_start(mm_radio_t * radio)
{
int ret = MM_ERROR_NONE;
_mmradio_set_volume(radio, radio->local_volume);
- ret = _mmradio_start_pipeline(radio);
+ ret = __mmradio_start_pipeline(radio);
if (ret) {
MMRADIO_LOG_ERROR("failed to start pipeline");
return ret;
MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
- ret = _mmradio_stop_pipeline(radio);
+ ret = __mmradio_stop_pipeline(radio);
if (ret) {
MMRADIO_LOG_ERROR("failed to stop pipeline");
return ret;
return ret;
}
-int _mmradio_realize_pipeline(mm_radio_t * radio)
+static int __mmradio_realize_pipeline(mm_radio_t * radio)
{
int ret = MM_ERROR_NONE;
int val = 0;
return ret;
}
-int _mmradio_start_pipeline(mm_radio_t * radio)
+static int __mmradio_start_pipeline(mm_radio_t * radio)
{
int ret = MM_ERROR_NONE;
GstStateChangeReturn ret_state;
return ret;
}
-int _mmradio_stop_pipeline(mm_radio_t * radio)
+static int __mmradio_stop_pipeline(mm_radio_t * radio)
{
int ret = MM_ERROR_NONE;
GstStateChangeReturn ret_state;
return ret;
}
-int _mmradio_destroy_pipeline(mm_radio_t * radio)
+static int __mmradio_destroy_pipeline(mm_radio_t * radio)
{
int ret = 0;
GstStateChangeReturn ret_state;
return MM_ERROR_NONE;
}
-int _mmradio_stop_scan(mm_radio_t * radio)
-{
- MMRADIO_LOG_FENTER();
-
- MMRADIO_CHECK_INSTANCE(radio);
- MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_STOP_SCAN);
-
- radio->thread[MM_RADIO_THREAD_SCAN].stop = true;
-
- MMRADIO_LOG_FLEAVE();
-
- return MM_ERROR_NONE;
-}
-
int _mmradio_get_signal_strength(mm_radio_t * radio, int *value)
{
MMRADIO_LOG_FENTER();
MMRADIO_RETURN_VAL_IF_FAIL(value, MM_ERROR_INVALID_ARGUMENT);
/* just return stored frequency if radio device is not ready */
- if (radio->radio_fd < 0) {
+ if (!radio->is_ready) {
MMRADIO_SLOG_DEBUG("Device not ready so sending 0");
*value = 0;
return MM_ERROR_NONE;
if (p_thread->stop)
break; /* doesn't need to post */
- __mmradio_msg_push(radio, MM_RADIO_MSG_SCAN_INFO, freq);
+ _mmradio_common_msg_push(radio, MM_RADIO_MSG_SCAN_INFO, freq);
emulatoridx++;
if (emulatoridx >= EMULATOR_FREQ_MAX)
break;
_mmradio_unmute(radio);
MMRADIO_SET_STATE(radio, MM_RADIO_STATE_PLAYING);
/* check if it's limit freq or not */
- if (__is_tunable_frequency(radio, freq)) {
+ if (_mmradio_common_is_tunable_frequency(radio, freq)) {
/* now tune to new frequency */
if (_mmradio_set_frequency(radio, freq))
MMRADIO_LOG_ERROR("failed to tune to new frequency");
p_thread->is_running = false;
if (p_thread->stop)
- __mmradio_msg_push(radio, MM_RADIO_MSG_SCAN_STOPPED, 0);
+ _mmradio_common_msg_push(radio, MM_RADIO_MSG_SCAN_STOPPED, 0);
else
- __mmradio_msg_push(radio, MM_RADIO_MSG_SCAN_FINISHED, 0);
+ _mmradio_common_msg_push(radio, MM_RADIO_MSG_SCAN_FINISHED, 0);
/* reset thread stop flag */
p_thread->stop = false;
return;
}
-bool __is_tunable_frequency(mm_radio_t * radio, int freq)
-{
- MMRADIO_LOG_FENTER();
-
- MMRADIO_CHECK_INSTANCE(radio);
-
- if (freq == radio->region_setting.band_max || freq == radio->region_setting.band_min)
- return false;
-
- MMRADIO_LOG_FLEAVE();
-
- return true;
-}
-
void __mmradio_seek_thread(mm_radio_t * radio)
{
int freq = 0;
emulatoridx = 0;
freq = 0;
+ MMRADIO_SEEK_THREAD_LOCK(radio);
MMRADIO_LOG_DEBUG("start radio->freq: %d", radio->freq);
if (radio->seek_direction == MM_RADIO_SEEK_UP) {
emulatoridx = EMULATOR_FREQ_MAX - 1;
}
}
+ MMRADIO_SEEK_THREAD_UNLOCK(radio);
radio->freq = freq;
MMRADIO_LOG_DEBUG("radio->freq: %d emulatoridx: %d", radio->freq, emulatoridx);
}
/* check if it's limit freq or not */
- if (__is_tunable_frequency(radio, freq)) {
+ if (_mmradio_common_is_tunable_frequency(radio, freq)) {
/* now tune to new frequency */
if (_mmradio_set_frequency(radio, freq)) {
MMRADIO_LOG_ERROR("failed to tune to new frequency");
radio->prev_seek_freq = freq;
MMRADIO_LOG_INFO("seeking : new frequency : [%d]", (int) freq);
p_thread->is_running = false;
- __mmradio_msg_push(radio, MM_RADIO_MSG_SEEK_FINISHED, freq);
+ _mmradio_common_msg_push(radio, MM_RADIO_MSG_SEEK_FINISHED, freq);
p_thread->stop = true;
continue;
SEEK_FAILED:
/* freq -1 means it's failed to seek */
- __mmradio_msg_push(radio, MM_RADIO_MSG_SEEK_FINISHED, -1);
+ _mmradio_common_msg_push(radio, MM_RADIO_MSG_SEEK_FINISHED, -1);
p_thread->stop = true;
p_thread->is_running = false;
}
return;
}
-static bool __mmradio_post_message(mm_radio_t * radio, enum MMMessageType msgtype, MMMessageParamType * param)
-{
- MMRADIO_CHECK_INSTANCE(radio);
-
- MMRADIO_LOG_FENTER();
-
- if (!radio->msg_cb) {
- MMRADIO_LOG_WARNING("failed to post a message because msg cb didn't register");
- return false;
- }
-
- MMRADIO_LOG_DEBUG("address of msg_cb : %p", radio->msg_cb);
-
- radio->msg_cb(msgtype, param, radio->msg_cb_param);
-
- MMRADIO_LOG_FLEAVE();
-
- return true;
-}
-
-static int __mmradio_check_state(mm_radio_t * radio, MMRadioCommand command)
-{
- MMRadioStateType radio_state = MM_RADIO_STATE_NUM;
-
- MMRADIO_LOG_FENTER();
-
- MMRADIO_CHECK_INSTANCE(radio);
-
- radio_state = __mmradio_get_state(radio);
-
- MMRADIO_LOG_DEBUG("incoming command : %d current state : %d", command, radio_state);
-
- switch (command) {
- case MMRADIO_COMMAND_CREATE:
- {
- if (radio_state != 0)
- goto NO_OP;
- }
- break;
-
- case MMRADIO_COMMAND_REALIZE:
- {
- if (radio_state == MM_RADIO_STATE_READY ||
- radio_state == MM_RADIO_STATE_PLAYING ||
- radio_state == MM_RADIO_STATE_SCANNING)
- goto NO_OP;
-
- if (radio_state == 0)
- goto INVALID_STATE;
- }
- break;
-
- case MMRADIO_COMMAND_UNREALIZE:
- {
- if (radio_state == MM_RADIO_STATE_NULL)
- goto NO_OP;
-
- /* we can call unrealize at any higher state */
- }
- break;
-
- case MMRADIO_COMMAND_START:
- {
- if (radio_state == MM_RADIO_STATE_PLAYING)
- goto NO_OP;
-
- if (radio_state != MM_RADIO_STATE_READY)
- goto INVALID_STATE;
- }
- break;
-
- case MMRADIO_COMMAND_STOP:
- {
- if (radio_state == MM_RADIO_STATE_READY)
- goto NO_OP;
-
- if (radio_state != MM_RADIO_STATE_PLAYING)
- goto INVALID_STATE;
- }
- break;
-
- case MMRADIO_COMMAND_START_SCAN:
- {
- if (radio_state == MM_RADIO_STATE_SCANNING)
- goto NO_OP;
-
- if (radio_state == MM_RADIO_STATE_NULL)
- goto INVALID_STATE;
- }
- break;
-
- case MMRADIO_COMMAND_STOP_SCAN:
- {
- if (radio_state == MM_RADIO_STATE_READY)
- goto NO_OP;
-
- if (radio_state != MM_RADIO_STATE_SCANNING)
- goto INVALID_STATE;
- }
- break;
-
- case MMRADIO_COMMAND_DESTROY:
- case MMRADIO_COMMAND_MUTE:
- case MMRADIO_COMMAND_UNMUTE:
- case MMRADIO_COMMAND_SET_FREQ:
- case MMRADIO_COMMAND_GET_FREQ:
- case MMRADIO_COMMAND_SET_REGION:
- {
- /* we can do it at any state */
- }
- break;
-
- case MMRADIO_COMMAND_SEEK:
- {
- if (radio_state != MM_RADIO_STATE_PLAYING)
- goto INVALID_STATE;
- }
- break;
-
- case MMRADIO_COMMAND_GET_REGION:
- {
- if (radio_state == MM_RADIO_STATE_NULL)
- goto INVALID_STATE;
- }
- break;
-
- default:
- MMRADIO_LOG_DEBUG("not handled in FSM. don't care it");
- break;
- }
-
- MMRADIO_LOG_DEBUG("status OK");
-
- radio->cmd = command;
-
- MMRADIO_LOG_FLEAVE();
-
- return MM_ERROR_NONE;
-
-INVALID_STATE:
- MMRADIO_LOG_WARNING("invalid state. current : %d command : %d", radio_state, command);
- MMRADIO_LOG_FLEAVE();
- return MM_ERROR_RADIO_INVALID_STATE;
-
-NO_OP:
- MMRADIO_LOG_WARNING("mm-radio is in the desired state(%d). doing noting", radio_state);
- MMRADIO_LOG_FLEAVE();
- return MM_ERROR_RADIO_NO_OP;
-
-}
-
-static bool __mmradio_set_state(mm_radio_t * radio, int new_state)
-{
- MMMessageParamType msg = { 0, };
- int msg_type = MM_MESSAGE_UNKNOWN;
-
- MMRADIO_LOG_FENTER();
-
- if (!radio) {
- MMRADIO_LOG_WARNING("calling set_state with invalid radio handle");
- return false;
- }
-
- if (radio->current_state == new_state && radio->pending_state == 0) {
- MMRADIO_LOG_WARNING("we are in same state");
- return true;
- }
-
- /* set state */
- radio->old_state = radio->current_state;
- radio->current_state = new_state;
-
- /* fill message param */
- msg.union_type = MM_MSG_UNION_STATE;
- msg.state.previous = radio->old_state;
- msg.state.current = radio->current_state;
-
- if (radio->interrupted_by_resource_conflict) {
- __mmradio_msg_push(radio, MM_RADIO_MSG_STATE_INTERRUPTED,
- MM_MSG_CODE_INTERRUPTED_BY_RESOURCE_CONFLICT);
- } else {
- msg_type = MM_MESSAGE_STATE_CHANGED;
- MMRADIO_POST_MSG(radio, msg_type, &msg);
- }
-
- MMRADIO_LOG_FLEAVE();
-
- return true;
-}
-
-static int __mmradio_get_state(mm_radio_t * radio)
-{
- MMRADIO_CHECK_INSTANCE(radio);
-
- MMRADIO_LOG_DEBUG("radio state : current : [%d] old : [%d] pending : [%d]",
- radio->current_state, radio->old_state, radio->pending_state);
-
- return radio->current_state;
-}
-
-int _mmradio_get_region_type(mm_radio_t * radio, MMRadioRegionType * type)
-{
- MMRADIO_LOG_FENTER();
- MMRADIO_CHECK_INSTANCE(radio);
- MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
-
- MMRADIO_RETURN_VAL_IF_FAIL(type, MM_ERROR_INVALID_ARGUMENT);
-
- *type = radio->region_setting.country;
-
- MMRADIO_LOG_FLEAVE();
- return MM_ERROR_NONE;
-}
-
-int _mmradio_get_region_frequency_range(mm_radio_t * radio, unsigned int *min_freq, unsigned int *max_freq)
-{
- MMRADIO_LOG_FENTER();
- MMRADIO_CHECK_INSTANCE(radio);
- MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
-
- MMRADIO_RETURN_VAL_IF_FAIL(min_freq && max_freq, MM_ERROR_INVALID_ARGUMENT);
-
- *min_freq = radio->region_setting.band_min;
- *max_freq = radio->region_setting.band_max;
-
- MMRADIO_LOG_FLEAVE();
- return MM_ERROR_NONE;
-}
-
-int _mmradio_get_channel_spacing(mm_radio_t * radio, unsigned int *ch_spacing)
-{
- MMRADIO_LOG_FENTER();
- MMRADIO_CHECK_INSTANCE(radio);
- MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
-
- MMRADIO_RETURN_VAL_IF_FAIL(ch_spacing, MM_ERROR_INVALID_ARGUMENT);
-
- *ch_spacing = radio->region_setting.channel_spacing;
-
- MMRADIO_LOG_FLEAVE();
- return MM_ERROR_NONE;
-}
-
static int __mmradio_get_wave_num(mm_radio_t * radio)
{
int val = 0;
return MM_ERROR_INVALID_ARGUMENT;
}
- if (radio->radio_fd < 0) {
+ if (!radio->is_ready) {
MMRADIO_LOG_DEBUG("radio device is not opened yet");
radio->local_volume = volume;
return MM_ERROR_NONE;
return MM_ERROR_NONE;
}
-int _mmradio_get_volume(mm_radio_t *radio, float *pVolume)
-{
- MMRADIO_LOG_FENTER();
-
- MMRADIO_CHECK_INSTANCE(radio);
- MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_VOLUME);
-
- MMRADIO_RETURN_VAL_IF_FAIL(pVolume, MM_ERROR_INVALID_ARGUMENT);
-
- MMRADIO_SLOG_DEBUG("volume : %f", radio->local_volume);
-
- *pVolume = radio->local_volume;
-
- MMRADIO_LOG_FLEAVE();
-
- return MM_ERROR_NONE;
-}
-
-static int __mmradio_create_thread_type(mm_radio_t *radio, MMRadioThreadTypes type)
-{
- MMRadioThread_t *p_thread = NULL;
-
- MMRADIO_LOG_FENTER();
-
- MMRADIO_CHECK_INSTANCE(radio);
-
- if (type >= MM_RADIO_THREAD_NUM) {
- MMRADIO_LOG_WARNING("wrong argument thread type");
- return MM_ERROR_RADIO_INTERNAL;
- }
-
- p_thread = &radio->thread[type];
- MMRADIO_CHECK_ARG(p_thread);
-
- MMRADIO_INIT_MUTEX(p_thread->mutex);
- MMRADIO_INIT_COND(p_thread->cond);
-
- MMRADIO_THREAD_LOCK(p_thread);
- p_thread->thread_id = pthread_create(&p_thread->thread, NULL,
- (void *)__mmradio_thread_function[type], (void *)radio);
- if (p_thread->thread_id) {
- MMRADIO_LOG_DEBUG("failed to create thread : [%d]", type);
- MMRADIO_THREAD_UNLOCK(p_thread);
- return MM_ERROR_RADIO_INTERNAL;
- }
-
- MMRADIO_LOG_DEBUG("wait for [%d] thread", type);
- MMRADIO_THREAD_WAIT(p_thread);
- MMRADIO_LOG_DEBUG("[%d] thread started", type);
- MMRADIO_THREAD_UNLOCK(p_thread);
-
- return MM_ERROR_NONE;
-
-ERROR:
- pthread_mutex_destroy(&p_thread->mutex);
- pthread_cond_destroy(&p_thread->cond);
- return MM_ERROR_RADIO_INTERNAL;
-
-}
-
-static int __mmradio_create_threads(mm_radio_t *radio)
-{
- int ret = MM_ERROR_NONE;
- int type = 0;
-
- MMRADIO_LOG_FENTER();
-
- MMRADIO_CHECK_INSTANCE(radio);
-
- MMRADIO_INIT_MUTEX(radio->cmd_lock);
-
- for (type = (int)MM_RADIO_THREAD_MSG; type < (int)MM_RADIO_THREAD_NUM; type++) {
- ret = __mmradio_create_thread_type(radio, (MMRadioThreadTypes)type);
- if (ret) {
- MMRADIO_LOG_ERROR("failed to create thread(%d)", type);
- while (--type >= (int)MM_RADIO_THREAD_MSG)
- __mmradio_destroy_thread_type(radio, (MMRadioThreadTypes)type);
- goto ERROR;
- }
- }
-
- MMRADIO_LOG_FLEAVE();
- return ret;
-
-ERROR:
- pthread_mutex_destroy(&radio->cmd_lock);
- MMRADIO_LOG_FLEAVE();
- return MM_ERROR_RADIO_INTERNAL;
-}
-
-static void __mmradio_destroy_thread_type(mm_radio_t *radio, MMRadioThreadTypes type)
-{
- MMRadioThread_t *p_thread = NULL;
- mm_radio_msg_t *msg = NULL;
- MMRADIO_LOG_FENTER();
-
- MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
-
- if (type >= MM_RADIO_THREAD_NUM) {
- MMRADIO_LOG_WARNING("wrong argument thread type");
- return;
- }
-
- p_thread = &radio->thread[type];
- MMRADIO_CHECK_ARG_RETURN_VOID(p_thread);
-
- if (p_thread->thread) {
- switch (type) {
- case MM_RADIO_THREAD_MSG:
- msg = g_slice_new0(mm_radio_msg_t);
- msg->msg_type = MM_RADIO_MSG_DESTROY;
- g_async_queue_push_front(radio->msg_queue, msg);
- pthread_join(p_thread->thread, NULL);
- p_thread->thread = 0;
- break;
- case MM_RADIO_THREAD_SEEK:
- case MM_RADIO_THREAD_SCAN:
- MMRADIO_THREAD_LOCK(p_thread);
- p_thread->thread_exit = true;
- MMRADIO_THREAD_SIGNAL(p_thread);
- MMRADIO_THREAD_UNLOCK(p_thread);
- pthread_join(p_thread->thread, NULL);
- p_thread->thread = 0;
- break;
- default:
- MMRADIO_LOG_WARNING("(%d)type isn't handled", type);
- break;
- }
- } else {
- MMRADIO_LOG_WARNING("(%d)thread is zero", type);
- }
-
- pthread_mutex_destroy(&p_thread->mutex);
- pthread_cond_destroy(&p_thread->cond);
-
- MMRADIO_LOG_FLEAVE();
-}
-
-static void __mmradio_destroy_threads(mm_radio_t *radio)
-{
- int type = (int)MM_RADIO_THREAD_NUM;
- MMRADIO_LOG_FENTER();
-
- MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
-
- while (--type >= 0)
- __mmradio_destroy_thread_type(radio, (MMRadioThreadTypes)type);
-
- pthread_mutex_destroy(&radio->cmd_lock);
-
- MMRADIO_LOG_FLEAVE();
-}
-
-
-void __mmradio_msg_push(mm_radio_t *radio, MMRadioMsgTypes msg_type, int msg_data)
-{
- mm_radio_msg_t *msg = g_slice_new0(mm_radio_msg_t);
-
- msg->msg_type = msg_type;
- msg->data = msg_data;
-
- MMRADIO_LOG_INFO("push msg_type: %d, msg_data: %d", (int)msg->msg_type, msg->data);
- g_async_queue_push(radio->msg_queue, msg);
-}
void __mmradio_msg_thread(mm_radio_t *radio)
{
*
*/
-/*===========================================================================================
-| |
-| INCLUDE FILES |
-| |
-========================================================================================== */
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <float.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <mm_error.h>
-#include <mm_message.h>
-
#include <hal/hal-radio.h>
-#include "mm_radio_priv_hal.h"
-
-/*===========================================================================================
- LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE
-========================================================================================== */
-/*---------------------------------------------------------------------------
- GLOBAL CONSTANT DEFINITIONS:
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
- IMPORTED VARIABLE DECLARATIONS:
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
- IMPORTED FUNCTION DECLARATIONS:
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
- LOCAL #defines:
----------------------------------------------------------------------------*/
-#define DEFAULT_DEVICE "/dev/radio0"
-#define TUNER_INDEX 0
-
-#define DEFAULT_FREQ 107700
-
-#define FREQ_FRAC 16
-#define RADIO_FREQ_FORMAT_SET(x_freq) ((x_freq) * FREQ_FRAC)
-#define RADIO_FREQ_FORMAT_GET(x_freq) ((x_freq) / FREQ_FRAC)
-/* If non-zero, wrap around when at the end of the frequency range, else stop seeking */
-#define DEFAULT_WRAP_AROUND 1
-
-#define RADIO_DEFAULT_REGION MM_RADIO_REGION_GROUP_USA
-#define READ_MAX_BUFFER_SIZE 1024
-/*---------------------------------------------------------------------------
- LOCAL CONSTANT DEFINITIONS:
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
- LOCAL DATA TYPE DEFINITIONS:
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
- GLOBAL VARIABLE DEFINITIONS:
----------------------------------------------------------------------------*/
-extern int errno;
-
-/*---------------------------------------------------------------------------
- LOCAL VARIABLE DEFINITIONS:
----------------------------------------------------------------------------*/
-/* radio region configuration table */
-static const MMRadioRegion_t region_table[] = {
- { /* North America, South America, South Korea, Taiwan, Australia */
- MM_RADIO_REGION_GROUP_USA, /* region type */
- MM_RADIO_DEEMPHASIS_75_US, /* de-emphasis */
- MM_RADIO_FREQ_MIN_87500_KHZ, /* min freq. */
- MM_RADIO_FREQ_MAX_108000_KHZ, /* max freq. */
- 50,
- },
- { /* China, Europe, Africa, Middle East, Hong Kong, India, Indonesia, Russia, Singapore */
- MM_RADIO_REGION_GROUP_EUROPE,
- MM_RADIO_DEEMPHASIS_50_US,
- MM_RADIO_FREQ_MIN_87500_KHZ,
- MM_RADIO_FREQ_MAX_108000_KHZ,
- 50,
- },
- {
- MM_RADIO_REGION_GROUP_JAPAN,
- MM_RADIO_DEEMPHASIS_50_US,
- MM_RADIO_FREQ_MIN_76100_KHZ,
- MM_RADIO_FREQ_MAX_89900_KHZ,
- 50,
- },
-};
+#include "mm_radio_priv.h"
-/*---------------------------------------------------------------------------
- LOCAL FUNCTION PROTOTYPES:
----------------------------------------------------------------------------*/
-static bool __mmradio_post_message(mm_radio_t *radio, enum MMMessageType msgtype, MMMessageParamType *param);
-static int __mmradio_check_state(mm_radio_t *radio, MMRadioCommand command);
-static int __mmradio_get_state(mm_radio_t *radio);
-static bool __mmradio_set_state(mm_radio_t *radio, int new_state);
-void _mmradio_seek_cancel(mm_radio_t *radio);
+static void __mmradio_seek_cancel(mm_radio_t *radio);
static void __mmradio_seek_thread(mm_radio_t *radio);
static void __mmradio_scan_thread(mm_radio_t *radio);
-static bool __is_tunable_frequency(mm_radio_t *radio, int freq);
-static int __mmradio_create_threads(mm_radio_t *radio);
-static void __mmradio_destroy_threads(mm_radio_t *radio);
-static int __mmradio_create_thread_type(mm_radio_t *radio, MMRadioThreadTypes type);
-static void __mmradio_destroy_thread_type(mm_radio_t *radio, MMRadioThreadTypes type);
-
static void __mmradio_msg_thread(mm_radio_t *radio);
-static void __mmradio_msg_push(mm_radio_t *radio, MMRadioMsgTypes msg_type, int msg_data);
static int __mmradio_prepare_radio_device(mm_radio_t *radio);
static void __mmradio_close_radio_device(mm_radio_t *radio);
+
typedef void (*thread_function)(mm_radio_t *);
thread_function __mmradio_thread_function[] = {
&__mmradio_msg_thread,
return ret;
}
-int _mmradio_apply_region(mm_radio_t *radio, MMRadioRegionType region, bool update)
-{
- int ret = MM_ERROR_NONE;
- int count = 0;
- int index = 0;
-
- MMRADIO_LOG_FENTER();
-
- MMRADIO_CHECK_INSTANCE(radio);
- MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_REGION);
-
- /* if needed, radio region must be updated.
- * Otherwise, just applying settings to device without it.
- */
- if (update) {
- count = ARRAY_SIZE(region_table);
-
- /* TODO: if auto is supported...get the region info. here */
-
- /* update radio region settings */
- for (index = 0; index < count; index++) {
- /* find the region from pre-defined table */
- if (region_table[index].country == region) {
- radio->region_setting.country = region_table[index].country;
- radio->region_setting.deemphasis = region_table[index].deemphasis;
- radio->region_setting.band_min = region_table[index].band_min;
- radio->region_setting.band_max = region_table[index].band_max;
- radio->region_setting.channel_spacing = region_table[index].channel_spacing;
- }
- }
- }
-
- MMRADIO_LOG_INFO("setting region - country: %d, de-emphasis: %d, band range: %d ~ %d KHz",
- radio->region_setting.country, radio->region_setting.deemphasis,
- radio->region_setting.band_min, radio->region_setting.band_max);
-
- MMRADIO_LOG_FLEAVE();
-
- return ret;
-}
-
int _mmradio_create_radio(mm_radio_t *radio)
{
int ret = MM_ERROR_NONE;
}
/* create mutex and thread */
- ret = __mmradio_create_threads(radio);
+ ret = _mmradio_common_create_threads(radio, (void **)__mmradio_thread_function);
if (ret) {
MMRADIO_LOG_ERROR("failed to create threads");
goto ERROR_THREAD;
if (ret != MM_ERROR_NONE)
MMRADIO_LOG_ERROR("failed to unregister resource manager");
ERROR_RESOURCE:
- __mmradio_destroy_threads(radio);
+ _mmradio_common_destroy_threads(radio);
ERROR_THREAD:
if (radio->msg_queue)
g_async_queue_unref(radio->msg_queue);
_mmradio_unrealize(radio);
/* destroy mutex and thread */
- __mmradio_destroy_threads(radio);
+ _mmradio_common_destroy_threads(radio);
if (radio->msg_queue)
g_async_queue_unref(radio->msg_queue);
return MM_ERROR_NONE;
}
-int _mmradio_set_message_callback(mm_radio_t *radio, MMMessageCallback callback, void *user_param)
-{
- MMRADIO_LOG_FENTER();
-
- MMRADIO_CHECK_INSTANCE(radio);
-
- radio->msg_cb = callback;
- radio->msg_cb_param = user_param;
-
- MMRADIO_LOG_DEBUG("msg_cb : %p msg_cb_param : %p", callback, user_param);
-
- MMRADIO_LOG_FLEAVE();
-
- return MM_ERROR_NONE;
-}
-
-int _mmradio_get_state(mm_radio_t *radio, int *pState)
-{
- int state = 0;
-
- MMRADIO_LOG_FENTER();
-
- MMRADIO_CHECK_INSTANCE(radio);
- MMRADIO_RETURN_VAL_IF_FAIL(pState, MM_ERROR_INVALID_ARGUMENT);
-
- state = __mmradio_get_state(radio);
-
- *pState = state;
-
- MMRADIO_LOG_FLEAVE();
-
- return MM_ERROR_NONE;
-}
-
int _mmradio_start(mm_radio_t *radio)
{
int ret = MM_ERROR_NONE;
MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_STOP);
/*cancel if any seek*/
- _mmradio_seek_cancel(radio);
+ __mmradio_seek_cancel(radio);
ret = sound_manager_stop_virtual_stream(radio->vstream);
if (ret != MM_ERROR_NONE) {
return MM_ERROR_NONE;
}
-void _mmradio_seek_cancel(mm_radio_t *radio)
+static void __mmradio_seek_cancel(mm_radio_t *radio)
{
MMRADIO_LOG_FENTER();
return MM_ERROR_NONE;
}
-int _mmradio_stop_scan(mm_radio_t *radio)
-{
- MMRADIO_LOG_FENTER();
-
- MMRADIO_CHECK_INSTANCE(radio);
- MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_STOP_SCAN);
-
- radio->thread[MM_RADIO_THREAD_SCAN].stop = true;
-
- MMRADIO_LOG_FLEAVE();
-
- return MM_ERROR_NONE;
-}
-
int _mmradio_get_signal_strength(mm_radio_t *radio, int *value)
{
int ret = MM_ERROR_NONE;
goto FINISHED;
}
- MMRADIO_HAL_SEEK_THREAD_LOCK(radio);
+ MMRADIO_SEEK_THREAD_LOCK(radio);
ret = hal_radio_seek(radio->hal_radio, MM_RADIO_SEEK_UP);
- MMRADIO_HAL_SEEK_THREAD_UNLOCK(radio);
+ MMRADIO_SEEK_THREAD_UNLOCK(radio);
if (ret) {
MMRADIO_LOG_ERROR("radio scanning error");
break;
break;
}
- __mmradio_msg_push(radio, MM_RADIO_MSG_SCAN_INFO, freq);
+ _mmradio_common_msg_push(radio, MM_RADIO_MSG_SCAN_INFO, freq);
}
}
p_thread->is_running = false;
if (p_thread->stop)
- __mmradio_msg_push(radio, MM_RADIO_MSG_SCAN_STOPPED, 0);
+ _mmradio_common_msg_push(radio, MM_RADIO_MSG_SCAN_STOPPED, 0);
else
- __mmradio_msg_push(radio, MM_RADIO_MSG_SCAN_FINISHED, 0);
+ _mmradio_common_msg_push(radio, MM_RADIO_MSG_SCAN_FINISHED, 0);
/* reset thread stop flag */
p_thread->stop = false;
}
-bool __is_tunable_frequency(mm_radio_t *radio, int freq)
-{
- MMRADIO_LOG_FENTER();
-
- MMRADIO_CHECK_INSTANCE(radio);
-
- if (freq >= radio->region_setting.band_max
- || freq <= radio->region_setting.band_min)
- return false;
-
- MMRADIO_LOG_FLEAVE();
-
- return true;
-}
-
void __mmradio_seek_thread(mm_radio_t *radio)
{
int ret = MM_ERROR_NONE;
}
freq = 0;
MMRADIO_LOG_DEBUG("try to seek ");
- MMRADIO_HAL_SEEK_THREAD_LOCK(radio);
+ MMRADIO_SEEK_THREAD_LOCK(radio);
MMRADIO_LOG_DEBUG("seek start");
ret = hal_radio_seek(radio->hal_radio, radio->seek_direction);
- MMRADIO_HAL_SEEK_THREAD_UNLOCK(radio);
+ MMRADIO_SEEK_THREAD_UNLOCK(radio);
if (ret) {
MMRADIO_LOG_ERROR("failed to seek radio hal");
goto SEEK_FAILED;
}
/* check if it's limit freq or not */
- if (__is_tunable_frequency(radio, freq)) {
+ if (_mmradio_common_is_tunable_frequency(radio, freq)) {
/* now tune to new frequency */
ret = hal_radio_set_frequency(radio->hal_radio, freq);
if (ret) {
radio->prev_seek_freq = (int)freq;
MMRADIO_LOG_INFO("seeking : new frequency : [%d]", (int) freq);
p_thread->is_running = false;
- __mmradio_msg_push(radio, MM_RADIO_MSG_SEEK_FINISHED, freq);
+ _mmradio_common_msg_push(radio, MM_RADIO_MSG_SEEK_FINISHED, freq);
continue;
SEEK_FAILED:
}
p_thread->is_running = false;
/* freq -1 means it's failed to seek */
- __mmradio_msg_push(radio, MM_RADIO_MSG_SEEK_FINISHED, -1);
+ _mmradio_common_msg_push(radio, MM_RADIO_MSG_SEEK_FINISHED, -1);
}
EXIT:
pthread_exit(NULL);
}
-static bool __mmradio_post_message(mm_radio_t *radio, enum MMMessageType msgtype, MMMessageParamType *param)
-{
- MMRADIO_CHECK_INSTANCE(radio);
-
- MMRADIO_LOG_FENTER();
-
- if (!radio->msg_cb) {
- MMRADIO_LOG_WARNING("failed to post a message because msg cb didn't register");
- return false;
- }
-
- MMRADIO_LOG_DEBUG("address of msg_cb : %p", radio->msg_cb);
-
- radio->msg_cb(msgtype, param, radio->msg_cb_param);
-
- MMRADIO_LOG_FLEAVE();
-
- return true;
-}
-
-static int __mmradio_check_state(mm_radio_t *radio, MMRadioCommand command)
-{
- MMRadioStateType radio_state = MM_RADIO_STATE_NUM;
-
- MMRADIO_LOG_FENTER();
-
- MMRADIO_CHECK_INSTANCE(radio);
-
- radio_state = __mmradio_get_state(radio);
-
- MMRADIO_LOG_INFO("incoming command : %d current state : %d", command, radio_state);
-
- switch (command) {
- case MMRADIO_COMMAND_CREATE:
- {
- if (radio_state != 0)
- goto NO_OP;
- }
- break;
-
- case MMRADIO_COMMAND_REALIZE:
- {
- if (radio_state == MM_RADIO_STATE_READY ||
- radio_state == MM_RADIO_STATE_PLAYING ||
- radio_state == MM_RADIO_STATE_SCANNING)
- goto NO_OP;
-
- if (radio_state == 0)
- goto INVALID_STATE;
- }
- break;
-
- case MMRADIO_COMMAND_UNREALIZE:
- {
- if (radio_state == MM_RADIO_STATE_NULL)
- goto NO_OP;
-
- /* we can call unrealize at any higher state */
- }
- break;
-
- case MMRADIO_COMMAND_START:
- {
- if (radio_state == MM_RADIO_STATE_PLAYING)
- goto NO_OP;
-
- if (radio_state != MM_RADIO_STATE_READY)
- goto INVALID_STATE;
- }
- break;
-
- case MMRADIO_COMMAND_STOP:
- {
- if (radio_state == MM_RADIO_STATE_READY)
- goto NO_OP;
-
- if (radio_state != MM_RADIO_STATE_PLAYING)
- goto INVALID_STATE;
- }
- break;
-
- case MMRADIO_COMMAND_START_SCAN:
- {
- if (radio_state == MM_RADIO_STATE_SCANNING)
- goto NO_OP;
-
- if (radio_state == MM_RADIO_STATE_NULL)
- goto INVALID_STATE;
- }
- break;
-
- case MMRADIO_COMMAND_STOP_SCAN:
- {
- if (radio_state == MM_RADIO_STATE_READY)
- goto NO_OP;
-
- if (radio_state != MM_RADIO_STATE_SCANNING)
- goto INVALID_STATE;
- }
- break;
-
- case MMRADIO_COMMAND_DESTROY:
- case MMRADIO_COMMAND_MUTE:
- case MMRADIO_COMMAND_UNMUTE:
- case MMRADIO_COMMAND_SET_FREQ:
- case MMRADIO_COMMAND_GET_FREQ:
- case MMRADIO_COMMAND_SET_REGION:
- case MMRADIO_COMMAND_SET_VOLUME:
- case MMRADIO_COMMAND_GET_VOLUME:
- {
- /* we can do it at any state */
- }
- break;
-
- case MMRADIO_COMMAND_SEEK:
- {
- if (radio_state != MM_RADIO_STATE_PLAYING)
- goto INVALID_STATE;
- }
- break;
-
- case MMRADIO_COMMAND_GET_REGION:
- {
- if (radio_state == MM_RADIO_STATE_NULL)
- goto INVALID_STATE;
- }
- break;
-
- default:
- MMRADIO_LOG_DEBUG("not handled in FSM. don't care it");
- break;
- }
-
- MMRADIO_LOG_DEBUG("status OK");
-
- radio->cmd = command;
-
- MMRADIO_LOG_FLEAVE();
-
- return MM_ERROR_NONE;
-
-INVALID_STATE:
- MMRADIO_LOG_WARNING("invalid state. current : %d command : %d", radio_state, command);
- MMRADIO_LOG_FLEAVE();
- return MM_ERROR_RADIO_INVALID_STATE;
-
-NO_OP:
- MMRADIO_LOG_WARNING("mm-radio is in the desired state(%d). doing noting", radio_state);
- MMRADIO_LOG_FLEAVE();
- return MM_ERROR_RADIO_NO_OP;
-
-}
-
-static bool __mmradio_set_state(mm_radio_t *radio, int new_state)
-{
- MMMessageParamType msg = { 0, };
- int msg_type = MM_MESSAGE_UNKNOWN;
-
- MMRADIO_LOG_FENTER();
-
- if (!radio) {
- MMRADIO_LOG_WARNING("calling set_state with invalid radio handle");
- return false;
- }
-
- if (radio->current_state == new_state && radio->pending_state == 0) {
- MMRADIO_LOG_WARNING("we are in same state");
- return true;
- }
-
- /* set state */
- radio->old_state = radio->current_state;
- radio->current_state = new_state;
-
- /* fill message param */
- msg.union_type = MM_MSG_UNION_STATE;
- msg.state.previous = radio->old_state;
- msg.state.current = radio->current_state;
-
- if (radio->interrupted_by_resource_conflict) {
- __mmradio_msg_push(radio, MM_RADIO_MSG_STATE_INTERRUPTED,
- MM_MSG_CODE_INTERRUPTED_BY_RESOURCE_CONFLICT);
- } else {
- msg_type = MM_MESSAGE_STATE_CHANGED;
- MMRADIO_POST_MSG(radio, msg_type, &msg);
- }
-
- MMRADIO_LOG_FLEAVE();
-
- return true;
-}
-
-static int __mmradio_get_state(mm_radio_t *radio)
-{
- MMRADIO_CHECK_INSTANCE(radio);
-
- MMRADIO_LOG_INFO("radio state : current : [%d] old : [%d] pending : [%d]",
- radio->current_state, radio->old_state, radio->pending_state);
-
- return radio->current_state;
-}
-
-int _mmradio_get_region_type(mm_radio_t *radio, MMRadioRegionType *type)
-{
- MMRADIO_LOG_FENTER();
- MMRADIO_CHECK_INSTANCE(radio);
- MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
-
- MMRADIO_RETURN_VAL_IF_FAIL(type, MM_ERROR_INVALID_ARGUMENT);
-
- *type = radio->region_setting.country;
-
- MMRADIO_LOG_FLEAVE();
- return MM_ERROR_NONE;
-}
-
-int _mmradio_get_region_frequency_range(mm_radio_t *radio, unsigned int *min_freq, unsigned int *max_freq)
-{
- MMRADIO_LOG_FENTER();
- MMRADIO_CHECK_INSTANCE(radio);
- MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
-
- MMRADIO_RETURN_VAL_IF_FAIL(min_freq && max_freq, MM_ERROR_INVALID_ARGUMENT);
-
- *min_freq = radio->region_setting.band_min;
- *max_freq = radio->region_setting.band_max;
-
- MMRADIO_LOG_FLEAVE();
- return MM_ERROR_NONE;
-}
-
-int _mmradio_get_channel_spacing(mm_radio_t *radio, unsigned int *ch_spacing)
-{
- MMRADIO_LOG_FENTER();
- MMRADIO_CHECK_INSTANCE(radio);
- MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
-
- MMRADIO_RETURN_VAL_IF_FAIL(ch_spacing, MM_ERROR_INVALID_ARGUMENT);
-
- *ch_spacing = radio->region_setting.channel_spacing;
-
- MMRADIO_LOG_FLEAVE();
- return MM_ERROR_NONE;
-}
-
int _mmradio_set_volume(mm_radio_t *radio, float volume)
{
MMRADIO_LOG_FENTER();
return MM_ERROR_NONE;
}
-int _mmradio_get_volume(mm_radio_t *radio, float *pVolume)
-{
- int ret = MM_ERROR_NONE;
-
- MMRADIO_LOG_FENTER();
-
- MMRADIO_CHECK_INSTANCE(radio);
- MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_VOLUME);
-
- MMRADIO_RETURN_VAL_IF_FAIL(pVolume, MM_ERROR_INVALID_ARGUMENT);
-
- *pVolume = radio->local_volume;
-
- MMRADIO_LOG_FLEAVE();
-
- return ret;
-}
-
-static int __mmradio_create_thread_type(mm_radio_t *radio, MMRadioThreadTypes type)
-{
- MMRadioThread_t *p_thread = NULL;
-
- MMRADIO_LOG_FENTER();
-
- MMRADIO_CHECK_INSTANCE(radio);
-
- if (type >= MM_RADIO_THREAD_NUM) {
- MMRADIO_LOG_WARNING("wrong argument thread type");
- return MM_ERROR_RADIO_INTERNAL;
- }
-
- p_thread = &radio->thread[type];
- p_thread->is_running = false;
- MMRADIO_CHECK_ARG(p_thread);
-
- MMRADIO_INIT_MUTEX(p_thread->mutex);
- MMRADIO_INIT_COND(p_thread->cond);
-
- p_thread->thread_id = pthread_create(&p_thread->thread, NULL,
- (void *)__mmradio_thread_function[type], (void *)radio);
- if (p_thread->thread_id) {
- MMRADIO_LOG_DEBUG("failed to create thread : [%d]", type);
- return MM_ERROR_RADIO_INTERNAL;
- }
-
- return MM_ERROR_NONE;
-
-ERROR:
- pthread_mutex_destroy(&p_thread->mutex);
- pthread_cond_destroy(&p_thread->cond);
- return MM_ERROR_RADIO_INTERNAL;
-
-}
-
-static int __mmradio_create_threads(mm_radio_t *radio)
-{
- int ret = MM_ERROR_NONE;
- int type = 0;
-
- MMRADIO_LOG_FENTER();
-
- MMRADIO_CHECK_INSTANCE(radio);
-
- MMRADIO_INIT_MUTEX(radio->cmd_lock);
- MMRADIO_INIT_MUTEX(radio->hal_seek_mutex);
-
- for (type = (int)MM_RADIO_THREAD_MSG; type < (int)MM_RADIO_THREAD_NUM; type++) {
- ret = __mmradio_create_thread_type(radio, (MMRadioThreadTypes)type);
- if (ret) {
- MMRADIO_LOG_ERROR("failed to create thread(%d)", type);
- while (--type >= (int)MM_RADIO_THREAD_MSG)
- __mmradio_destroy_thread_type(radio, (MMRadioThreadTypes)type);
- goto ERROR;
- }
- }
-
- MMRADIO_LOG_FLEAVE();
- return ret;
-
-ERROR:
- pthread_mutex_destroy(&radio->cmd_lock);
- pthread_mutex_destroy(&radio->hal_seek_mutex);
-
- MMRADIO_LOG_FLEAVE();
- return MM_ERROR_RADIO_INTERNAL;
-}
-
-static void __mmradio_destroy_thread_type(mm_radio_t *radio, MMRadioThreadTypes type)
-{
- MMRadioThread_t *p_thread = NULL;
- mm_radio_msg_t *msg = NULL;
- MMRADIO_LOG_FENTER();
-
- MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
-
- if (type >= MM_RADIO_THREAD_NUM) {
- MMRADIO_LOG_WARNING("wrong argument thread type");
- return;
- }
-
- p_thread = &radio->thread[type];
- MMRADIO_CHECK_ARG_RETURN_VOID(p_thread);
-
- if (p_thread->thread) {
- switch (type) {
- case MM_RADIO_THREAD_MSG:
- msg = g_slice_new0(mm_radio_msg_t);
- if (!msg) {
- MMRADIO_LOG_ERROR("failed to get mm_radio_msg_t");
- } else {
- msg->msg_type = MM_RADIO_MSG_DESTROY;
- g_async_queue_push_front(radio->msg_queue, msg);
- pthread_join(p_thread->thread, NULL);
- p_thread->thread = 0;
- }
- break;
- case MM_RADIO_THREAD_SEEK:
- case MM_RADIO_THREAD_SCAN:
- MMRADIO_THREAD_LOCK(p_thread);
- p_thread->thread_exit = true;
- p_thread->is_running = true;
- MMRADIO_THREAD_SIGNAL(p_thread);
- MMRADIO_THREAD_UNLOCK(p_thread);
- pthread_join(p_thread->thread, NULL);
- p_thread->thread = 0;
- break;
- default:
- MMRADIO_LOG_WARNING("(%d)type isn't handled", type);
- }
- } else {
- MMRADIO_LOG_WARNING("(%d)thread is zero", type);
- }
-
- pthread_mutex_destroy(&p_thread->mutex);
- pthread_cond_destroy(&p_thread->cond);
-
- MMRADIO_LOG_FLEAVE();
-}
-
-static void __mmradio_destroy_threads(mm_radio_t *radio)
-{
- int type = (int)MM_RADIO_THREAD_NUM;
- MMRADIO_LOG_FENTER();
-
- MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
-
- while (--type >= 0)
- __mmradio_destroy_thread_type(radio, (MMRadioThreadTypes)type);
-
- pthread_mutex_destroy(&radio->cmd_lock);
- pthread_mutex_destroy(&radio->hal_seek_mutex);
-
- MMRADIO_LOG_FLEAVE();
-}
-
-void __mmradio_msg_push(mm_radio_t *radio, MMRadioMsgTypes msg_type, int msg_data)
-{
- mm_radio_msg_t *msg = g_slice_new0(mm_radio_msg_t);
- if (!msg) {
- MMRADIO_LOG_ERROR("NULL msg pointer");
- return;
- }
-
- msg->msg_type = msg_type;
- msg->data = msg_data;
-
- MMRADIO_LOG_INFO("push msg_type: %d, msg_data: %d", (int)msg->msg_type, msg->data);
- g_async_queue_push(radio->msg_queue, msg);
-}
-
void __mmradio_msg_thread(mm_radio_t *radio)
{
*/
#include "mm_radio_rm.h"
-#ifdef TIZEN_FEATURE_RADIO_HAL
-#include "mm_radio_priv_hal.h"
-#else
-#include "mm_radio_priv_emul.h"
-#endif
+#include "mm_radio_priv.h"
#include <mm_error.h>
#include <sys/types.h>
#include <unistd.h>
#include <gmock/gmock.h>
#include "mm_radio.h"
-#ifdef TIZEN_FEATURE_RADIO_HAL
-#include "mm_radio_priv_hal.h"
-#else
-#include "mm_radio_priv_emul.h"
-#endif
+#include "mm_radio_priv.h"
#undef LOG_TAG
#define LOG_TAG "GTEST_LIBMM_RADIO"