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 "base.h" 20 #include "support/property.h" 21 22 bt_property_t *property_copy_array(const bt_property_t *properties, size_t count) { 23 bt_property_t *clone = calloc(sizeof(bt_property_t), count); 24 if (!clone) { 25 return NULL; 26 } 27 28 memcpy(&clone[0], &properties[0], sizeof(bt_property_t) * count); 29 for (size_t i = 0; i < count; ++i) { 30 clone[i].val = calloc(clone[i].len, 1); 31 memcpy(clone[i].val, properties[i].val, clone[i].len); 32 } 33 34 return clone; 35 } 36 37 bt_property_t *property_new_name(const char *name) { 38 bt_bdname_t *bdname = calloc(sizeof(bt_bdname_t), 1); 39 bt_property_t *property = calloc(sizeof(bt_property_t), 1); 40 41 property->type = BT_PROPERTY_BDNAME; 42 property->val = bdname; 43 property->len = sizeof(bt_bdname_t); 44 45 strlcpy((char *)bdname->name, name, sizeof(bdname->name)); 46 47 return property; 48 } 49 50 bt_property_t *property_new_discovery_timeout(uint32_t timeout) { 51 uint32_t *val = malloc(sizeof(uint32_t)); 52 bt_property_t *property = malloc(sizeof(bt_property_t)); 53 54 property->type = BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT; 55 property->val = val; 56 property->len = sizeof(uint32_t); 57 58 *val = timeout; 59 60 return property; 61 } 62 63 // Warning: not thread safe. 64 const char *property_extract_name(const bt_property_t *property) { 65 static char name[250] = { 0 }; 66 if (!property || property->type != BT_PROPERTY_BDNAME || !property->val) { 67 return NULL; 68 } 69 70 strncpy(name, (const char *)((bt_bdname_t *)property->val)->name, property->len); 71 name[sizeof(name) - 1] = '\0'; 72 73 return name; 74 } 75 76 bool property_equals(const bt_property_t *p1, const bt_property_t *p2) { 77 // Two null properties are not the same. May need to revisit that 78 // decision when we have a test case that exercises that condition. 79 if (!p1 || !p2 || p1->type != p2->type) { 80 return false; 81 } 82 83 // Although the Bluetooth name is a 249-byte array, the implementation 84 // treats it like a variable-length array with its size specified in the 85 // property's `len` field. We special-case the equivalence of BDNAME 86 // types here by truncating the larger, zero-padded name to its string 87 // length and comparing against the shorter name. 88 // 89 // Note: it may be the case that both strings are zero-padded but that 90 // hasn't come up yet so this implementation doesn't handle it. 91 if (p1->type == BT_PROPERTY_BDNAME && p1->len != p2->len) { 92 const bt_property_t *shorter = p1, *longer = p2; 93 if (p1->len > p2->len) { 94 shorter = p2; 95 longer = p1; 96 } 97 return strlen((const char *)longer->val) == (size_t)shorter->len && !memcmp(longer->val, shorter->val, shorter->len); 98 } 99 100 return p1->len == p2->len && !memcmp(p1->val, p2->val, p1->len); 101 } 102 103 void property_free(bt_property_t *property) { 104 property_free_array(property, 1); 105 } 106 107 void property_free_array(bt_property_t *properties, size_t count) { 108 for (size_t i = 0; i < count; ++i) { 109 free(properties[i].val); 110 } 111 112 free(properties); 113 } 114