blob: ff4952c50ca967425ade1f4b5d9b58f6abb4d120 [file] [log] [blame]
/******************************************************************************
*
* Copyright (C) 2014 Google, Inc.
*
* 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 <signal.h>
#include <time.h>
#include "base.h"
#include "support/hal.h"
static bool set_wake_alarm(uint64_t delay_millis, bool should_wake, alarm_cb cb, void *data);
static int acquire_wake_lock(const char *lock_name);
static int release_wake_lock(const char *lock_name);
static const bluetooth_device_t *bt_device;
static bt_os_callouts_t callouts = {
sizeof(bt_os_callouts_t),
set_wake_alarm,
acquire_wake_lock,
release_wake_lock,
};
bool hal_open(bt_callbacks_t *callbacks) {
hw_module_t *module;
if (hw_get_module(BT_STACK_MODULE_ID, (hw_module_t const **)&module)) {
return false;
}
hw_device_t *device;
if (module->methods->open(module, BT_STACK_MODULE_ID, &device)) {
return false;
}
bt_device = (bluetooth_device_t *)device;
bt_interface = bt_device->get_bluetooth_interface();
if (!bt_interface) {
bt_device->common.close((hw_device_t *)&bt_device->common);
bt_device = NULL;
return false;
}
bool success = (bt_interface->init(callbacks) == BT_STATUS_SUCCESS);
success = success && (bt_interface->set_os_callouts(&callouts) == BT_STATUS_SUCCESS);
return success;
}
void hal_close() {
if (bt_interface) {
bt_interface->cleanup();
bt_interface = NULL;
}
if (bt_device) {
bt_device->common.close((hw_device_t *)&bt_device->common);
bt_device = NULL;
}
}
static bool set_wake_alarm(uint64_t delay_millis, bool should_wake, alarm_cb cb, void *data) {
static timer_t timer;
static bool timer_created;
if (!timer_created) {
struct sigevent sigevent;
memset(&sigevent, 0, sizeof(sigevent));
sigevent.sigev_notify = SIGEV_THREAD;
sigevent.sigev_notify_function = (void (*)(union sigval))cb;
sigevent.sigev_value.sival_ptr = data;
timer_create(CLOCK_MONOTONIC, &sigevent, &timer);
timer_created = true;
}
struct itimerspec new_value;
new_value.it_value.tv_sec = delay_millis / 1000;
new_value.it_value.tv_nsec = (delay_millis % 1000) * 1000 * 1000;
new_value.it_interval.tv_sec = 0;
new_value.it_interval.tv_nsec = 0;
timer_settime(timer, 0, &new_value, NULL);
return true;
}
static int acquire_wake_lock(const char *lock_name) {
return BT_STATUS_SUCCESS;
}
static int release_wake_lock(const char *lock_name) {
return BT_STATUS_SUCCESS;
}