12a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati/******************************************************************************
22a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati *
32a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati *  Copyright (C) 2014 Google, Inc.
42a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati *
52a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati *  Licensed under the Apache License, Version 2.0 (the "License");
62a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati *  you may not use this file except in compliance with the License.
72a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati *  You may obtain a copy of the License at:
82a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati *
92a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati *  http://www.apache.org/licenses/LICENSE-2.0
102a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati *
112a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati *  Unless required by applicable law or agreed to in writing, software
122a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati *  distributed under the License is distributed on an "AS IS" BASIS,
132a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati *  See the License for the specific language governing permissions and
152a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati *  limitations under the License.
162a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati *
172a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati ******************************************************************************/
182a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati
19138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati#include <signal.h>
20138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati#include <time.h>
21138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati
222a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati#include "base.h"
232a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati#include "support/hal.h"
242a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati
25138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavatistatic bool set_wake_alarm(uint64_t delay_millis, bool should_wake, alarm_cb cb, void *data);
26138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavatistatic int acquire_wake_lock(const char *lock_name);
27138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavatistatic int release_wake_lock(const char *lock_name);
28138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati
292a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavatistatic const bluetooth_device_t *bt_device;
302a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati
31138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavatistatic bt_os_callouts_t callouts = {
32138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati  sizeof(bt_os_callouts_t),
33138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati  set_wake_alarm,
34138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati  acquire_wake_lock,
35138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati  release_wake_lock,
36138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati};
37138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati
382a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavatibool hal_open(bt_callbacks_t *callbacks) {
392a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati  hw_module_t *module;
402a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati  if (hw_get_module(BT_STACK_MODULE_ID, (hw_module_t const **)&module)) {
412a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati    return false;
422a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati  }
432a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati
442a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati  hw_device_t *device;
452a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati  if (module->methods->open(module, BT_STACK_MODULE_ID, &device)) {
462a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati    return false;
472a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati  }
482a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati
492a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati  bt_device = (bluetooth_device_t *)device;
502a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati  bt_interface = bt_device->get_bluetooth_interface();
512a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati  if (!bt_interface) {
522a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati    bt_device->common.close((hw_device_t *)&bt_device->common);
532a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati    bt_device = NULL;
542a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati    return false;
552a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati  }
562a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati
57138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati  bool success = (bt_interface->init(callbacks) == BT_STATUS_SUCCESS);
58138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati  success = success && (bt_interface->set_os_callouts(&callouts) == BT_STATUS_SUCCESS);
59138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati  return success;
602a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati}
612a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati
622a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavativoid hal_close() {
632a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati  if (bt_interface) {
642a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati    bt_interface->cleanup();
652a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati    bt_interface = NULL;
662a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati  }
672a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati
682a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati  if (bt_device) {
692a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati    bt_device->common.close((hw_device_t *)&bt_device->common);
702a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati    bt_device = NULL;
712a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati  }
722a73b6deaaf2c12dec215ddeab1e0223c9f28446Sharvil Nanavati}
73138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati
74138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavatistatic bool set_wake_alarm(uint64_t delay_millis, bool should_wake, alarm_cb cb, void *data) {
75138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati  static timer_t timer;
76138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati  static bool timer_created;
77138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati
78138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati  if (!timer_created) {
79138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati    struct sigevent sigevent;
80138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati    memset(&sigevent, 0, sizeof(sigevent));
81138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati    sigevent.sigev_notify = SIGEV_THREAD;
82138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati    sigevent.sigev_notify_function = (void (*)(union sigval))cb;
83138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati    sigevent.sigev_value.sival_ptr = data;
84138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati    timer_create(CLOCK_MONOTONIC, &sigevent, &timer);
85138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati    timer_created = true;
86138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati  }
87138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati
88138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati  struct itimerspec new_value;
89138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati  new_value.it_value.tv_sec = delay_millis / 1000;
90138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati  new_value.it_value.tv_nsec = (delay_millis % 1000) * 1000 * 1000;
91138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati  new_value.it_interval.tv_sec = 0;
92138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati  new_value.it_interval.tv_nsec = 0;
93138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati  timer_settime(timer, 0, &new_value, NULL);
94138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati
95138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati  return true;
96138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati}
97138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati
98138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavatistatic int acquire_wake_lock(const char *lock_name) {
99138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati  return BT_STATUS_SUCCESS;
100138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati}
101138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati
102138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavatistatic int release_wake_lock(const char *lock_name) {
103138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati  return BT_STATUS_SUCCESS;
104138ca8b8b121c17ff3ee9a7c10d76246a5c7325bSharvil Nanavati}
105