1/******************************************************************************
2 *
3 *  Copyright (C) 2014 Google, Inc.
4 *
5 *  Licensed under the Apache License, Version 2.0 (the "License");
6 *  you may not use this file except in compliance with the License.
7 *  You may obtain a copy of the License at:
8 *
9 *  http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 *
17 ******************************************************************************/
18
19#include <signal.h>
20#include <time.h>
21
22#include "base.h"
23#include "support/hal.h"
24
25static bool set_wake_alarm(uint64_t delay_millis, bool should_wake, alarm_cb cb, void *data);
26static int acquire_wake_lock(const char *lock_name);
27static int release_wake_lock(const char *lock_name);
28
29static const bluetooth_device_t *bt_device;
30
31static bt_os_callouts_t callouts = {
32  sizeof(bt_os_callouts_t),
33  set_wake_alarm,
34  acquire_wake_lock,
35  release_wake_lock,
36};
37
38bool hal_open(bt_callbacks_t *callbacks) {
39  hw_module_t *module;
40  if (hw_get_module(BT_STACK_MODULE_ID, (hw_module_t const **)&module)) {
41    return false;
42  }
43
44  hw_device_t *device;
45  if (module->methods->open(module, BT_STACK_MODULE_ID, &device)) {
46    return false;
47  }
48
49  bt_device = (bluetooth_device_t *)device;
50  bt_interface = bt_device->get_bluetooth_interface();
51  if (!bt_interface) {
52    bt_device->common.close((hw_device_t *)&bt_device->common);
53    bt_device = NULL;
54    return false;
55  }
56
57  bool success = (bt_interface->init(callbacks) == BT_STATUS_SUCCESS);
58  success = success && (bt_interface->set_os_callouts(&callouts) == BT_STATUS_SUCCESS);
59  return success;
60}
61
62void hal_close() {
63  if (bt_interface) {
64    bt_interface->cleanup();
65    bt_interface = NULL;
66  }
67
68  if (bt_device) {
69    bt_device->common.close((hw_device_t *)&bt_device->common);
70    bt_device = NULL;
71  }
72}
73
74static bool set_wake_alarm(uint64_t delay_millis, bool should_wake, alarm_cb cb, void *data) {
75  static timer_t timer;
76  static bool timer_created;
77
78  if (!timer_created) {
79    struct sigevent sigevent;
80    memset(&sigevent, 0, sizeof(sigevent));
81    sigevent.sigev_notify = SIGEV_THREAD;
82    sigevent.sigev_notify_function = (void (*)(union sigval))cb;
83    sigevent.sigev_value.sival_ptr = data;
84    timer_create(CLOCK_MONOTONIC, &sigevent, &timer);
85    timer_created = true;
86  }
87
88  struct itimerspec new_value;
89  new_value.it_value.tv_sec = delay_millis / 1000;
90  new_value.it_value.tv_nsec = (delay_millis % 1000) * 1000 * 1000;
91  new_value.it_interval.tv_sec = 0;
92  new_value.it_interval.tv_nsec = 0;
93  timer_settime(timer, 0, &new_value, NULL);
94
95  return true;
96}
97
98static int acquire_wake_lock(const char *lock_name) {
99  return BT_STATUS_SUCCESS;
100}
101
102static int release_wake_lock(const char *lock_name) {
103  return BT_STATUS_SUCCESS;
104}
105