4 * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #define _OAL_EVENT_DISPATCHER_C_
27 #include "oal-hardware.h"
28 #include "oal-event.h"
29 #include "oal-utils.h"
30 #include "oal-manager.h"
32 #define EVENT_TRACE(fmt, args...) {LOG_(LOG_ID_SYSTEM, DLOG_INFO, "OAL_EVENT", GREEN(fmt), ##args); \
33 LOG_(LOG_ID_MAIN, DLOG_INFO, LOG_TAG, GREEN("[OAL_EVENT]"fmt), ##args); }
41 static GMainContext *event_thread_context;
42 static oal_event_callback event_handler_cb;
43 GMainLoop *event_loop;
45 void _bt_event_dispatcher_deinit()
49 BT_DBG("OAL event loop guit");
50 g_main_loop_quit(event_loop);
56 static gpointer __event_handler_loop(gpointer user_data)
60 /* Set up the thread�s context and run it forever. */
61 g_main_context_push_thread_default(event_thread_context);
63 event_loop = g_main_loop_new(event_thread_context, FALSE);
65 ret = oal_lib_init(NULL);
67 BT_WARN("oal_lib_init failed, trying again...");
68 } while (ret == FALSE);
70 g_main_loop_run(event_loop);
71 BT_DBG("OAL event loop quited");
74 g_main_loop_unref(event_loop);
78 g_main_context_pop_thread_default(event_thread_context);
79 g_main_context_unref(event_thread_context);
84 static void event_data_free(event_t *event_info)
86 if (event_info->event_data)
87 g_free(event_info->event_data);
88 g_slice_free(event_t, event_info);
91 /* Convert an idle callback into a call to dispatch_idle(). */
92 static gboolean dispatch_idle(gpointer user_data)
94 event_t *event_info = user_data;
97 if (NULL == event_handler_cb)
98 BT_ERR("Upstream handler not registered");
100 (*event_handler_cb)(event_info->event, event_info->event_data, event_info->size);
103 return G_SOURCE_REMOVE;
106 static gboolean need_same_context(oal_event_t event)
118 void _bt_event_dispatcher_init(oal_event_callback cb)
120 event_handler_cb = cb;
122 /* Spawn a background thread and pass it a reference to its
123 * GMainContext. Retain a reference for use in this thread
125 event_thread_context = g_main_context_new();
126 g_thread_new("OALEventScheduler", __event_handler_loop, NULL);
129 void send_event_no_trace(oal_event_t event, gpointer event_data, gsize len)
133 /* Create a data closure to pass all the desired variables
134 * between threads. */
135 event_info = g_slice_new0(event_t);
136 event_info->event = event;
137 event_info->size = len;
138 event_info->event_data = event_data;
139 /* Invoke the function. */
141 if (need_same_context(event)) {
142 BT_INFO("Without context change");
143 dispatch_idle(event_info);
144 event_data_free(event_info);
146 g_main_context_invoke_full(event_thread_context,
147 G_PRIORITY_DEFAULT, dispatch_idle,
149 (GDestroyNotify) event_data_free);
152 void send_event_bda_trace(oal_event_t event, gpointer event_data, gsize len, bt_address_t *address)
154 if (event != OAL_EVENT_BLE_REMOTE_DEVICE_FOUND) {
157 EVENT_TRACE("[%s] %s", bdt_bd2str(address, &bdstr), str_event[event]);
159 EVENT_TRACE(" %s", str_event[event]);
161 send_event_no_trace(event, event_data, len);
164 void send_event(oal_event_t event, gpointer event_data, gsize len)
166 send_event_bda_trace(event, event_data, len, NULL);
168 #undef _OAL_EVENT_DISPATCHER_C_