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 #include "osi/include/hash_functions.h"
25 #include "osi/include/hash_map.h"
26
27 #define TIMER_BUCKET_COUNT 4
28
29 static bool set_wake_alarm(uint64_t delay_millis, bool should_wake, alarm_cb cb, void *data);
30 static int acquire_wake_lock(const char *lock_name);
31 static int release_wake_lock(const char *lock_name);
32
33 static const bluetooth_device_t *bt_device;
34
35 static bt_os_callouts_t callouts = {
36 sizeof(bt_os_callouts_t),
37 set_wake_alarm,
38 acquire_wake_lock,
39 release_wake_lock,
40 };
41
hal_open(bt_callbacks_t * callbacks)42 bool hal_open(bt_callbacks_t *callbacks) {
43 hw_module_t *module;
44 if (hw_get_module(BT_STACK_MODULE_ID, (hw_module_t const **)&module)) {
45 return false;
46 }
47
48 hw_device_t *device;
49 if (module->methods->open(module, BT_STACK_MODULE_ID, &device)) {
50 return false;
51 }
52
53 bt_device = (bluetooth_device_t *)device;
54 bt_interface = bt_device->get_bluetooth_interface();
55 if (!bt_interface) {
56 bt_device->common.close((hw_device_t *)&bt_device->common);
57 bt_device = NULL;
58 return false;
59 }
60
61 bool success = (bt_interface->init(callbacks) == BT_STATUS_SUCCESS);
62 success = success && (bt_interface->set_os_callouts(&callouts) == BT_STATUS_SUCCESS);
63 return success;
64 }
65
hal_close()66 void hal_close() {
67 if (bt_interface) {
68 bt_interface->cleanup();
69 bt_interface = NULL;
70 }
71
72 if (bt_device) {
73 bt_device->common.close((hw_device_t *)&bt_device->common);
74 bt_device = NULL;
75 }
76 }
77
set_wake_alarm(uint64_t delay_millis,bool should_wake,alarm_cb cb,void * data)78 static bool set_wake_alarm(uint64_t delay_millis, bool should_wake, alarm_cb cb, void *data) {
79 static hash_map_t *timers;
80
81 if (!timers) {
82 timers = hash_map_new(TIMER_BUCKET_COUNT, hash_function_pointer, NULL, NULL, NULL);
83 }
84
85 timer_t *timer = hash_map_get(timers, cb);
86 if (!timer) {
87 timer = malloc(sizeof(timer_t));
88 hash_map_set(timers, cb, timer);
89
90 struct sigevent sigevent;
91 memset(&sigevent, 0, sizeof(sigevent));
92 sigevent.sigev_notify = SIGEV_THREAD;
93 sigevent.sigev_notify_function = (void (*)(union sigval))cb;
94 sigevent.sigev_value.sival_ptr = data;
95 timer_create(CLOCK_MONOTONIC, &sigevent, timer);
96 }
97
98 struct itimerspec new_value;
99 new_value.it_value.tv_sec = delay_millis / 1000;
100 new_value.it_value.tv_nsec = (delay_millis % 1000) * 1000 * 1000;
101 new_value.it_interval.tv_sec = 0;
102 new_value.it_interval.tv_nsec = 0;
103 timer_settime(*timer, 0, &new_value, NULL);
104
105 return true;
106 }
107
acquire_wake_lock(const char * lock_name)108 static int acquire_wake_lock(const char *lock_name) {
109 return BT_STATUS_SUCCESS;
110 }
111
release_wake_lock(const char * lock_name)112 static int release_wake_lock(const char *lock_name) {
113 return BT_STATUS_SUCCESS;
114 }
115