2 * Open Adaptation Layer (OAL)
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.
24 #include <sys/prctl.h>
28 #include <bluetooth.h>
30 #include "oal-internal.h"
31 #include "oal-event.h"
32 #include <oal-hardware.h>
34 #define BT_HAL_LIB_NAME "libbluetooth.default.so"
37 #define HAL_LIBRARY_PATH "/usr/lib64"
39 #define HAL_LIBRARY_PATH "/usr/lib"
42 #define LIB_PATH_SIZE 50
43 #define LIB_NAME_SIZE 50
45 static const hw_module_t* module = NULL;
46 static const bt_interface_t *blued_api = NULL;
47 static bluetooth_device_t* bt_device = NULL;
49 static gboolean unload_libs(gpointer data);
50 static bluetooth_device_t* load_hal_lib(void);
51 static const bt_interface_t * get_stack_interface(bluetooth_device_t* bt_device);
52 static int load(const char *libname, const struct hw_module_t **module);
53 static int unload(const struct hw_module_t *module);
55 oal_status_t oal_mgr_init_internal(void)
57 bt_device = load_hal_lib();
59 if (bt_device == NULL) {
60 BT_ERR("HAL Library loading failed");
61 return OAL_STATUS_INTERNAL_ERROR;
64 blued_api = get_stack_interface(bt_device);
66 if (blued_api == NULL) {
67 BT_ERR("Stack Interface failed");
68 return OAL_STATUS_INTERNAL_ERROR;
71 device_mgr_init(blued_api);
73 return adapter_mgr_init(blued_api);
76 oal_status_t oal_bt_init(oal_event_callback cb)
78 API_TRACE("Version: %s", OAL_VERSION_STR);
79 _bt_event_dispatcher_init(cb);
80 return OAL_STATUS_PENDING;
83 void oal_bt_deinit(void)
90 _bt_event_dispatcher_deinit();
96 void oal_mgr_cleanup(void)
101 void oal_mgr_stack_reload(void)
103 /*TODO Unsupported */
106 gboolean oal_lib_init(gpointer data)
109 BT_INFO("Going to check Chip Attachment...");
111 if (hw_is_module_ready() == OAL_STATUS_SUCCESS) {
112 if (hw_get_chip_type() == BT_CHIP_TYPE_UNKNOWN) {
113 BT_DBG("Chip Type Unknown, starting timer...");
115 ret = oal_mgr_init_internal();
116 if (OAL_STATUS_SUCCESS == ret)
117 send_event(OAL_EVENT_OAL_INITIALISED_SUCCESS, NULL, 0);
119 send_event(OAL_EVENT_OAL_INITIALISED_FAILED, NULL, 0);
122 BT_DBG("Chip Not Yet Ready, try again...");
128 static gboolean unload_libs(gpointer data)
130 bt_device->common.close((hw_device_t*)bt_device);
131 unload((hw_module_t const*)module);
136 static bluetooth_device_t* load_hal_lib(void)
141 BT_DBG("Loading HAL lib");
142 if (module == NULL) {
143 switch (hw_get_chip_type()) {
144 case BT_CHIP_TYPE_PLATFORM:
145 BT_INFO("Tizen Platform BT chip: Tizen Platform HAL library will be loaded");
146 err = load(BT_HAL_LIB_NAME, (const hw_module_t **)&module);
149 BT_WARN("Chip type Unknown, So no Library Load");
154 BT_WARN("Lib already loaded");
157 err = module->methods->open(module, BT_HARDWARE_MODULE_ID, &device);
159 bt_device = (bluetooth_device_t *)device;
160 BT_INFO("HAL Library loaded successfullly");
169 static const bt_interface_t * get_stack_interface(bluetooth_device_t* bt_device)
171 const bt_interface_t *blued_api = NULL;
172 /* Get the Bluetooth interface */
173 blued_api = bt_device->get_bluetooth_interface();
178 static int load(const char *libname, const struct hw_module_t **module)
180 int status = -ENOENT;
181 char libpath[LIB_PATH_SIZE];
183 struct hw_module_t *hmi;
185 OAL_CHECK_PARAMETER(libname, return);
187 snprintf(libpath, sizeof(libpath), "%s/%s", HAL_LIBRARY_PATH, libname);
188 BT_INFO("Loading Library: %s", libpath);
191 * load the symbols resolving undefined symbols before
192 * dlopen returns. Since RTLD_GLOBAL is not or'd in with
193 * RTLD_NOW the external symbols will not be global
196 prctl(666, "[bt-service] Load Lib S", strlen("[bt-service] Load Lib S"));
198 handle = dlopen(libpath, RTLD_NOW);
199 if (handle == NULL) {
200 char const *err_str = dlerror();
201 BT_ERR("load: module=%s\n%s", libpath, err_str ? err_str : "unknown");
206 prctl(666, "[bt-service] Load Lib E", strlen("[bt-service] Load Lib E"));
208 /* Get the address of the struct hal_module_info. */
209 const char *sym = HAL_MODULE_INFO_SYM_AS_STR;
210 hmi = (struct hw_module_t *)dlsym(handle, sym);
212 BT_ERR("load: couldn't find symbol %s", sym);
217 /* Check that the id matches */
218 if (strcmp(BT_HARDWARE_MODULE_ID, hmi->id) != 0) {
219 BT_ERR("load: id=%s != hmi->id=%s", BT_HARDWARE_MODULE_ID, hmi->id);
230 if (handle != NULL) {
235 BT_DBG("loaded HAL id=%s libpath=%s hmi=%p handle=%p",
236 BT_HARDWARE_MODULE_ID, libpath, hmi, handle);
242 static int unload(const struct hw_module_t *module)
247 ret = dlclose(module->dso);
250 BT_ERR("dlclose failed:%d", ret);
251 BT_WARN("Issues with dl: %s\n", dlerror());
255 void oal_set_debug_mode(gboolean mode)
257 /*TODO Unsupported */
260 gboolean oal_get_debug_mode(void)
262 /*TODO Unsupported */
266 const char *oal_get_stack_name(void)
268 return module ? module->name : NULL;