18a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati/******************************************************************************
28a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati *
38a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati *  Copyright (C) 2014 Google, Inc.
48a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati *
58a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati *  Licensed under the Apache License, Version 2.0 (the "License");
68a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati *  you may not use this file except in compliance with the License.
78a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati *  You may obtain a copy of the License at:
88a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati *
98a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati *  http://www.apache.org/licenses/LICENSE-2.0
108a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati *
118a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati *  Unless required by applicable law or agreed to in writing, software
128a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati *  distributed under the License is distributed on an "AS IS" BASIS,
138a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
148a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati *  See the License for the specific language governing permissions and
158a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati *  limitations under the License.
168a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati *
178a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati ******************************************************************************/
188a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati
198a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati#include <assert.h>
208a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati#include <ctype.h>
218a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati#include <stdio.h>
228a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati#include <string.h>
238a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati
2495b74f252f534ec757aab1fc08e086e02b2cfe8dSharvil Nanavati#include "btcore/include/bdaddr.h"
258a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati
268a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavatibool bdaddr_is_empty(const bt_bdaddr_t *addr) {
278a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati  assert(addr != NULL);
288a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati
298a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati  uint8_t zero[sizeof(bt_bdaddr_t)] = { 0 };
308a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati  return memcmp(addr, &zero, sizeof(bt_bdaddr_t)) == 0;
318a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati}
328a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati
338a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavatibool bdaddr_equals(const bt_bdaddr_t *first, const bt_bdaddr_t *second) {
348a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati  assert(first != NULL);
358a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati  assert(second != NULL);
368a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati
378a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati  return memcmp(first, second, sizeof(bt_bdaddr_t)) == 0;
388a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati}
398a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati
407f3bb6c9205b917891da894954865f1bab248cf2Chris Mantonbt_bdaddr_t *bdaddr_copy(bt_bdaddr_t *dest, const bt_bdaddr_t *src) {
417f3bb6c9205b917891da894954865f1bab248cf2Chris Manton  assert(dest != NULL);
427f3bb6c9205b917891da894954865f1bab248cf2Chris Manton  assert(src != NULL);
437f3bb6c9205b917891da894954865f1bab248cf2Chris Manton
447f3bb6c9205b917891da894954865f1bab248cf2Chris Manton  return (bt_bdaddr_t *)memcpy(dest, src, sizeof(bt_bdaddr_t));
457f3bb6c9205b917891da894954865f1bab248cf2Chris Manton}
467f3bb6c9205b917891da894954865f1bab248cf2Chris Manton
478a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavaticonst char *bdaddr_to_string(const bt_bdaddr_t *addr, char *string, size_t size) {
488a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati  assert(addr != NULL);
498a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati  assert(string != NULL);
508a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati
518a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati  if (size < 18)
528a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati    return NULL;
538a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati
548a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati  const uint8_t *ptr = addr->address;
558a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati  sprintf(string, "%02x:%02x:%02x:%02x:%02x:%02x",
568a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati           ptr[0], ptr[1], ptr[2],
578a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati           ptr[3], ptr[4], ptr[5]);
588a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati  return string;
598a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati}
608a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati
618a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavatibool string_is_bdaddr(const char *string) {
628a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati  assert(string != NULL);
638a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati
648a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati  size_t len = strlen(string);
658a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati  if (len != 17)
668a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati    return false;
678a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati
688a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati  for (size_t i = 0; i < len; ++i) {
698a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati    // Every 3rd char must be ':'.
708a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati    if (((i + 1) % 3) == 0 && string[i] != ':')
718a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati      return false;
728a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati
738a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati    // All other chars must be a hex digit.
748a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati    if (((i + 1) % 3) != 0 && !isxdigit(string[i]))
758a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati      return false;
768a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati  }
778a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati  return true;
788a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati}
798a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati
808a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavatibool string_to_bdaddr(const char *string, bt_bdaddr_t *addr) {
818a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati  assert(string != NULL);
828a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati  assert(addr != NULL);
838a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati
848a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati  bt_bdaddr_t new_addr;
858a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati  uint8_t *ptr = new_addr.address;
868a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati  bool ret = sscanf(string, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
878a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati      &ptr[0], &ptr[1], &ptr[2], &ptr[3], &ptr[4], &ptr[5]) == 6;
888a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati
898a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati  if (ret)
908a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati    memcpy(addr, &new_addr, sizeof(bt_bdaddr_t));
918a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati
928a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati  return ret;
938a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati}
9405d0366413bedc16b4189b9e74395fe4b11ba41aZach Johnson
9505d0366413bedc16b4189b9e74395fe4b11ba41aZach Johnsonhash_index_t hash_function_bdaddr(const void *key) {
9605d0366413bedc16b4189b9e74395fe4b11ba41aZach Johnson  hash_index_t hash = 5381;
9705d0366413bedc16b4189b9e74395fe4b11ba41aZach Johnson  const char *bytes = (const char *)key;
9805d0366413bedc16b4189b9e74395fe4b11ba41aZach Johnson  for (size_t i = 0; i < sizeof(bt_bdaddr_t); ++i)
9905d0366413bedc16b4189b9e74395fe4b11ba41aZach Johnson    hash = ((hash << 5) + hash) + bytes[i];
10005d0366413bedc16b4189b9e74395fe4b11ba41aZach Johnson  return hash;
10105d0366413bedc16b4189b9e74395fe4b11ba41aZach Johnson}
102