/****************************************************************************** * * 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); }