12234929d21efedb2cb38190fa8162da90be94886Zach Johnson/******************************************************************************
22234929d21efedb2cb38190fa8162da90be94886Zach Johnson *
32234929d21efedb2cb38190fa8162da90be94886Zach Johnson *  Copyright (C) 2014 Google, Inc.
42234929d21efedb2cb38190fa8162da90be94886Zach Johnson *
52234929d21efedb2cb38190fa8162da90be94886Zach Johnson *  Licensed under the Apache License, Version 2.0 (the "License");
62234929d21efedb2cb38190fa8162da90be94886Zach Johnson *  you may not use this file except in compliance with the License.
72234929d21efedb2cb38190fa8162da90be94886Zach Johnson *  You may obtain a copy of the License at:
82234929d21efedb2cb38190fa8162da90be94886Zach Johnson *
92234929d21efedb2cb38190fa8162da90be94886Zach Johnson *  http://www.apache.org/licenses/LICENSE-2.0
102234929d21efedb2cb38190fa8162da90be94886Zach Johnson *
112234929d21efedb2cb38190fa8162da90be94886Zach Johnson *  Unless required by applicable law or agreed to in writing, software
122234929d21efedb2cb38190fa8162da90be94886Zach Johnson *  distributed under the License is distributed on an "AS IS" BASIS,
132234929d21efedb2cb38190fa8162da90be94886Zach Johnson *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142234929d21efedb2cb38190fa8162da90be94886Zach Johnson *  See the License for the specific language governing permissions and
152234929d21efedb2cb38190fa8162da90be94886Zach Johnson *  limitations under the License.
162234929d21efedb2cb38190fa8162da90be94886Zach Johnson *
172234929d21efedb2cb38190fa8162da90be94886Zach Johnson ******************************************************************************/
182234929d21efedb2cb38190fa8162da90be94886Zach Johnson
192234929d21efedb2cb38190fa8162da90be94886Zach Johnson#define LOG_TAG "bt_classic_peer"
202234929d21efedb2cb38190fa8162da90be94886Zach Johnson
212234929d21efedb2cb38190fa8162da90be94886Zach Johnson#include <assert.h>
222234929d21efedb2cb38190fa8162da90be94886Zach Johnson#include <cutils/log.h>
232234929d21efedb2cb38190fa8162da90be94886Zach Johnson#include <pthread.h>
242234929d21efedb2cb38190fa8162da90be94886Zach Johnson#include <stdbool.h>
252234929d21efedb2cb38190fa8162da90be94886Zach Johnson
262234929d21efedb2cb38190fa8162da90be94886Zach Johnson#include "btcore/include/module.h"
272234929d21efedb2cb38190fa8162da90be94886Zach Johnson#include "device/include/classic/peer.h"
282234929d21efedb2cb38190fa8162da90be94886Zach Johnson#include "osi/include/allocator.h"
292234929d21efedb2cb38190fa8162da90be94886Zach Johnson#include "osi/include/future.h"
302234929d21efedb2cb38190fa8162da90be94886Zach Johnson#include "osi/include/hash_map.h"
312234929d21efedb2cb38190fa8162da90be94886Zach Johnson#include "osi/include/osi.h"
322234929d21efedb2cb38190fa8162da90be94886Zach Johnson
332234929d21efedb2cb38190fa8162da90be94886Zach Johnsonstruct classic_peer_t {
342234929d21efedb2cb38190fa8162da90be94886Zach Johnson  bt_bdaddr_t address;
352234929d21efedb2cb38190fa8162da90be94886Zach Johnson};
362234929d21efedb2cb38190fa8162da90be94886Zach Johnson
372234929d21efedb2cb38190fa8162da90be94886Zach Johnsonstatic const size_t number_of_address_buckets = 42;
382234929d21efedb2cb38190fa8162da90be94886Zach Johnson
392234929d21efedb2cb38190fa8162da90be94886Zach Johnsonstatic bool initialized;
402234929d21efedb2cb38190fa8162da90be94886Zach Johnsonstatic pthread_mutex_t bag_of_peers_lock;
412234929d21efedb2cb38190fa8162da90be94886Zach Johnsonstatic hash_map_t *peers_by_address;
422234929d21efedb2cb38190fa8162da90be94886Zach Johnson
432234929d21efedb2cb38190fa8162da90be94886Zach Johnsonstatic bool bdaddr_equality_fn(const void *x, const void *y);
442234929d21efedb2cb38190fa8162da90be94886Zach Johnson
452234929d21efedb2cb38190fa8162da90be94886Zach Johnson// Module lifecycle functions
462234929d21efedb2cb38190fa8162da90be94886Zach Johnson
472234929d21efedb2cb38190fa8162da90be94886Zach Johnsonstatic future_t *init(void) {
482234929d21efedb2cb38190fa8162da90be94886Zach Johnson  peers_by_address = hash_map_new(
492234929d21efedb2cb38190fa8162da90be94886Zach Johnson    number_of_address_buckets,
502234929d21efedb2cb38190fa8162da90be94886Zach Johnson    hash_function_bdaddr,
512234929d21efedb2cb38190fa8162da90be94886Zach Johnson    NULL,
522234929d21efedb2cb38190fa8162da90be94886Zach Johnson    osi_free,
532234929d21efedb2cb38190fa8162da90be94886Zach Johnson    bdaddr_equality_fn);
542234929d21efedb2cb38190fa8162da90be94886Zach Johnson
552234929d21efedb2cb38190fa8162da90be94886Zach Johnson  pthread_mutex_init(&bag_of_peers_lock, NULL);
562234929d21efedb2cb38190fa8162da90be94886Zach Johnson
572234929d21efedb2cb38190fa8162da90be94886Zach Johnson  initialized = true;
582234929d21efedb2cb38190fa8162da90be94886Zach Johnson  return NULL;
592234929d21efedb2cb38190fa8162da90be94886Zach Johnson}
602234929d21efedb2cb38190fa8162da90be94886Zach Johnson
612234929d21efedb2cb38190fa8162da90be94886Zach Johnsonstatic future_t *clean_up(void) {
622234929d21efedb2cb38190fa8162da90be94886Zach Johnson  initialized = false;
632234929d21efedb2cb38190fa8162da90be94886Zach Johnson
642234929d21efedb2cb38190fa8162da90be94886Zach Johnson  hash_map_free(peers_by_address);
652234929d21efedb2cb38190fa8162da90be94886Zach Johnson  peers_by_address = NULL;
662234929d21efedb2cb38190fa8162da90be94886Zach Johnson
672234929d21efedb2cb38190fa8162da90be94886Zach Johnson  pthread_mutex_destroy(&bag_of_peers_lock);
682234929d21efedb2cb38190fa8162da90be94886Zach Johnson  return NULL;
692234929d21efedb2cb38190fa8162da90be94886Zach Johnson}
702234929d21efedb2cb38190fa8162da90be94886Zach Johnson
712234929d21efedb2cb38190fa8162da90be94886Zach Johnsonconst module_t classic_peer_module = {
722234929d21efedb2cb38190fa8162da90be94886Zach Johnson  .name = CLASSIC_PEER_MODULE,
732234929d21efedb2cb38190fa8162da90be94886Zach Johnson  .init = init,
742234929d21efedb2cb38190fa8162da90be94886Zach Johnson  .start_up = NULL,
752234929d21efedb2cb38190fa8162da90be94886Zach Johnson  .shut_down = NULL,
762234929d21efedb2cb38190fa8162da90be94886Zach Johnson  .clean_up = clean_up,
772234929d21efedb2cb38190fa8162da90be94886Zach Johnson  .dependencies = {
782234929d21efedb2cb38190fa8162da90be94886Zach Johnson    NULL
792234929d21efedb2cb38190fa8162da90be94886Zach Johnson  }
802234929d21efedb2cb38190fa8162da90be94886Zach Johnson};
812234929d21efedb2cb38190fa8162da90be94886Zach Johnson
822234929d21efedb2cb38190fa8162da90be94886Zach Johnson// Interface functions
832234929d21efedb2cb38190fa8162da90be94886Zach Johnson
842234929d21efedb2cb38190fa8162da90be94886Zach Johnsonclassic_peer_t *classic_peer_by_address(bt_bdaddr_t *address) {
852234929d21efedb2cb38190fa8162da90be94886Zach Johnson  assert(initialized);
862234929d21efedb2cb38190fa8162da90be94886Zach Johnson  assert(address != NULL);
872234929d21efedb2cb38190fa8162da90be94886Zach Johnson
882234929d21efedb2cb38190fa8162da90be94886Zach Johnson  classic_peer_t *peer = hash_map_get(peers_by_address, address);
892234929d21efedb2cb38190fa8162da90be94886Zach Johnson
902234929d21efedb2cb38190fa8162da90be94886Zach Johnson  if (!peer) {
912234929d21efedb2cb38190fa8162da90be94886Zach Johnson    pthread_mutex_lock(&bag_of_peers_lock);
922234929d21efedb2cb38190fa8162da90be94886Zach Johnson
932234929d21efedb2cb38190fa8162da90be94886Zach Johnson    // Make sure it didn't get added in the meantime
942234929d21efedb2cb38190fa8162da90be94886Zach Johnson    peer = hash_map_get(peers_by_address, address);
952234929d21efedb2cb38190fa8162da90be94886Zach Johnson    if (peer)
962234929d21efedb2cb38190fa8162da90be94886Zach Johnson      goto done;
972234929d21efedb2cb38190fa8162da90be94886Zach Johnson
982234929d21efedb2cb38190fa8162da90be94886Zach Johnson    // Splice in a new peer struct on behalf of the caller.
992234929d21efedb2cb38190fa8162da90be94886Zach Johnson    peer = osi_calloc(sizeof(classic_peer_t));
1002234929d21efedb2cb38190fa8162da90be94886Zach Johnson    peer->address = *address;
1012234929d21efedb2cb38190fa8162da90be94886Zach Johnson    hash_map_set(peers_by_address, &peer->address, peer);
1022234929d21efedb2cb38190fa8162da90be94886Zach Johnson
1032234929d21efedb2cb38190fa8162da90be94886Zach Johnson    pthread_mutex_unlock(&bag_of_peers_lock);
1042234929d21efedb2cb38190fa8162da90be94886Zach Johnson  }
1052234929d21efedb2cb38190fa8162da90be94886Zach Johnson
1062234929d21efedb2cb38190fa8162da90be94886Zach Johnsondone:
1072234929d21efedb2cb38190fa8162da90be94886Zach Johnson  return peer;
1082234929d21efedb2cb38190fa8162da90be94886Zach Johnson}
1092234929d21efedb2cb38190fa8162da90be94886Zach Johnson
1102234929d21efedb2cb38190fa8162da90be94886Zach Johnsonconst bt_bdaddr_t *classic_peer_get_address(classic_peer_t *peer) {
1112234929d21efedb2cb38190fa8162da90be94886Zach Johnson  assert(peer != NULL);
1122234929d21efedb2cb38190fa8162da90be94886Zach Johnson  return &peer->address;
1132234929d21efedb2cb38190fa8162da90be94886Zach Johnson}
1142234929d21efedb2cb38190fa8162da90be94886Zach Johnson
1152234929d21efedb2cb38190fa8162da90be94886Zach Johnson// Internal functions
1162234929d21efedb2cb38190fa8162da90be94886Zach Johnson
1172234929d21efedb2cb38190fa8162da90be94886Zach Johnson// Wrapper for bdaddr_equals used in the hash map of peers by address
1182234929d21efedb2cb38190fa8162da90be94886Zach Johnsonstatic bool bdaddr_equality_fn(const void *x, const void *y) {
1192234929d21efedb2cb38190fa8162da90be94886Zach Johnson  return bdaddr_equals((bt_bdaddr_t *)x, (bt_bdaddr_t *)y);
1202234929d21efedb2cb38190fa8162da90be94886Zach Johnson}
121