blob: ea2c5c4b95f3008a48e99da06c21900c144db7a1 [file] [log] [blame]
/******************************************************************************
*
* Copyright (C) 2014 Google, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#include "base.h"
#include "support/property.h"
bt_property_t *property_copy_array(const bt_property_t *properties, size_t count) {
bt_property_t *clone = calloc(sizeof(bt_property_t), count);
if (!clone) {
return NULL;
}
memcpy(&clone[0], &properties[0], sizeof(bt_property_t) * count);
for (size_t i = 0; i < count; ++i) {
clone[i].val = calloc(clone[i].len, 1);
memcpy(clone[i].val, properties[i].val, clone[i].len);
}
return clone;
}
bt_property_t *property_new_name(const char *name) {
bt_bdname_t *bdname = calloc(sizeof(bt_bdname_t), 1);
bt_property_t *property = calloc(sizeof(bt_property_t), 1);
property->type = BT_PROPERTY_BDNAME;
property->val = bdname;
property->len = sizeof(bt_bdname_t);
strlcpy((char *)bdname->name, name, sizeof(bdname->name));
return property;
}
bt_property_t *property_new_discovery_timeout(uint32_t timeout) {
uint32_t *val = malloc(sizeof(uint32_t));
bt_property_t *property = malloc(sizeof(bt_property_t));
property->type = BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT;
property->val = val;
property->len = sizeof(uint32_t);
*val = timeout;
return property;
}
// Warning: not thread safe.
const char *property_extract_name(const bt_property_t *property) {
static char name[250] = { 0 };
if (!property || property->type != BT_PROPERTY_BDNAME || !property->val) {
return NULL;
}
strncpy(name, (const char *)((bt_bdname_t *)property->val)->name, property->len);
name[sizeof(name) - 1] = '\0';
return name;
}
bool property_equals(const bt_property_t *p1, const bt_property_t *p2) {
// Two null properties are not the same. May need to revisit that
// decision when we have a test case that exercises that condition.
if (!p1 || !p2 || p1->type != p2->type) {
return false;
}
// Although the Bluetooth name is a 249-byte array, the implementation
// treats it like a variable-length array with its size specified in the
// property's `len` field. We special-case the equivalence of BDNAME
// types here by truncating the larger, zero-padded name to its string
// length and comparing against the shorter name.
//
// Note: it may be the case that both strings are zero-padded but that
// hasn't come up yet so this implementation doesn't handle it.
if (p1->type == BT_PROPERTY_BDNAME && p1->len != p2->len) {
const bt_property_t *shorter = p1, *longer = p2;
if (p1->len > p2->len) {
shorter = p2;
longer = p1;
}
return strlen((const char *)longer->val) == (size_t)shorter->len && !memcmp(longer->val, shorter->val, shorter->len);
}
return p1->len == p2->len && !memcmp(p1->val, p2->val, p1->len);
}
void property_free(bt_property_t *property) {
property_free_array(property, 1);
}
void property_free_array(bt_property_t *properties, size_t count) {
for (size_t i = 0; i < count; ++i) {
free(properties[i].val);
}
free(properties);
}