Home | History | Annotate | Download | only in support
      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 
     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 
     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 
     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 
    108 static int acquire_wake_lock(const char *lock_name) {
    109   return BT_STATUS_SUCCESS;
    110 }
    111 
    112 static int release_wake_lock(const char *lock_name) {
    113   return BT_STATUS_SUCCESS;
    114 }
    115