Sharvil Nanavati | 3cf59ef | 2014-04-09 22:20:40 -0700 | [diff] [blame] | 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 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 19 | #include "btcore/include/property.h" |
Chris Manton | 97c5444 | 2015-01-07 13:34:18 -0800 | [diff] [blame] | 20 | #include <assert.h> |
Etan Cohen | 3e59b5b | 2015-03-31 17:15:53 -0700 | [diff] [blame] | 21 | #include <string.h> |
Chris Manton | 97c5444 | 2015-01-07 13:34:18 -0800 | [diff] [blame] | 22 | #include "btcore/include/bdaddr.h" |
| 23 | #include "btcore/include/device_class.h" |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 24 | #include "btcore/include/uuid.h" |
| 25 | #include "osi/include/allocator.h" |
| 26 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 27 | static bt_property_t* property_new_(void* val, size_t len, |
| 28 | bt_property_type_t type); |
Sharvil Nanavati | 3cf59ef | 2014-04-09 22:20:40 -0700 | [diff] [blame] | 29 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 30 | bt_property_t* property_copy_array(const bt_property_t* properties, |
| 31 | size_t count) { |
Chris Manton | 97c5444 | 2015-01-07 13:34:18 -0800 | [diff] [blame] | 32 | assert(properties != NULL); |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 33 | bt_property_t* clone = |
| 34 | static_cast<bt_property_t*>(osi_calloc(sizeof(bt_property_t) * count)); |
Sharvil Nanavati | 3cf59ef | 2014-04-09 22:20:40 -0700 | [diff] [blame] | 35 | |
| 36 | memcpy(&clone[0], &properties[0], sizeof(bt_property_t) * count); |
| 37 | for (size_t i = 0; i < count; ++i) { |
Chris Manton | 5c26224 | 2014-10-14 22:00:32 -0700 | [diff] [blame] | 38 | clone[i].val = osi_calloc(clone[i].len); |
Sharvil Nanavati | 3cf59ef | 2014-04-09 22:20:40 -0700 | [diff] [blame] | 39 | memcpy(clone[i].val, properties[i].val, clone[i].len); |
| 40 | } |
| 41 | |
| 42 | return clone; |
| 43 | } |
| 44 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 45 | bt_property_t* property_copy(bt_property_t* dest, const bt_property_t* src) { |
Chris Manton | 97c5444 | 2015-01-07 13:34:18 -0800 | [diff] [blame] | 46 | assert(dest != NULL); |
| 47 | assert(src != NULL); |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 48 | return (bt_property_t*)memcpy(dest, src, sizeof(bt_property_t)); |
Chris Manton | 97c5444 | 2015-01-07 13:34:18 -0800 | [diff] [blame] | 49 | } |
| 50 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 51 | bool property_equals(const bt_property_t* p1, const bt_property_t* p2) { |
Sharvil Nanavati | 3cf59ef | 2014-04-09 22:20:40 -0700 | [diff] [blame] | 52 | // Two null properties are not the same. May need to revisit that |
| 53 | // decision when we have a test case that exercises that condition. |
| 54 | if (!p1 || !p2 || p1->type != p2->type) { |
| 55 | return false; |
| 56 | } |
| 57 | |
| 58 | // Although the Bluetooth name is a 249-byte array, the implementation |
| 59 | // treats it like a variable-length array with its size specified in the |
| 60 | // property's `len` field. We special-case the equivalence of BDNAME |
| 61 | // types here by truncating the larger, zero-padded name to its string |
| 62 | // length and comparing against the shorter name. |
| 63 | // |
| 64 | // Note: it may be the case that both strings are zero-padded but that |
| 65 | // hasn't come up yet so this implementation doesn't handle it. |
| 66 | if (p1->type == BT_PROPERTY_BDNAME && p1->len != p2->len) { |
| 67 | const bt_property_t *shorter = p1, *longer = p2; |
| 68 | if (p1->len > p2->len) { |
| 69 | shorter = p2; |
| 70 | longer = p1; |
| 71 | } |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 72 | return strlen((const char*)longer->val) == (size_t)shorter->len && |
| 73 | !memcmp(longer->val, shorter->val, shorter->len); |
Sharvil Nanavati | 3cf59ef | 2014-04-09 22:20:40 -0700 | [diff] [blame] | 74 | } |
| 75 | |
| 76 | return p1->len == p2->len && !memcmp(p1->val, p2->val, p1->len); |
| 77 | } |
| 78 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 79 | bt_property_t* property_new_addr(const bt_bdaddr_t* addr) { |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 80 | assert(addr != NULL); |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 81 | return property_new_((void*)addr, sizeof(bt_bdaddr_t), BT_PROPERTY_BDADDR); |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 82 | } |
| 83 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 84 | bt_property_t* property_new_device_class(const bt_device_class_t* dc) { |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 85 | assert(dc != NULL); |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 86 | return property_new_((void*)dc, sizeof(bt_device_class_t), |
| 87 | BT_PROPERTY_CLASS_OF_DEVICE); |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 88 | } |
| 89 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 90 | bt_property_t* property_new_device_type(bt_device_type_t type) { |
| 91 | return property_new_((void*)&type, sizeof(bt_device_type_t), |
| 92 | BT_PROPERTY_TYPE_OF_DEVICE); |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 93 | } |
| 94 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 95 | bt_property_t* property_new_discovery_timeout(const uint32_t timeout) { |
| 96 | return property_new_((void*)&timeout, sizeof(uint32_t), |
| 97 | BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT); |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 98 | } |
| 99 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 100 | bt_property_t* property_new_name(const char* name) { |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 101 | assert(name != NULL); |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 102 | return property_new_((void*)name, sizeof(bt_bdname_t), BT_PROPERTY_BDNAME); |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 103 | } |
| 104 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 105 | bt_property_t* property_new_rssi(int8_t rssi) { |
| 106 | return property_new_((void*)&rssi, sizeof(int8_t), BT_PROPERTY_REMOTE_RSSI); |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 107 | } |
| 108 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 109 | bt_property_t* property_new_scan_mode(bt_scan_mode_t scan_mode) { |
| 110 | return property_new_((void*)&scan_mode, sizeof(bt_scan_mode_t), |
| 111 | BT_PROPERTY_ADAPTER_SCAN_MODE); |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 112 | } |
| 113 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 114 | bt_property_t* property_new_uuids(const bt_uuid_t* uuid, size_t count) { |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 115 | assert(uuid != NULL); |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 116 | return property_new_((void*)uuid, sizeof(bt_uuid_t) * count, |
| 117 | BT_PROPERTY_UUIDS); |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 118 | } |
| 119 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 120 | void property_free(bt_property_t* property) { |
Sharvil Nanavati | 3cf59ef | 2014-04-09 22:20:40 -0700 | [diff] [blame] | 121 | property_free_array(property, 1); |
| 122 | } |
| 123 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 124 | void property_free_array(bt_property_t* properties, size_t count) { |
| 125 | if (properties == NULL) return; |
Chris Manton | 97c5444 | 2015-01-07 13:34:18 -0800 | [diff] [blame] | 126 | |
Sharvil Nanavati | 3cf59ef | 2014-04-09 22:20:40 -0700 | [diff] [blame] | 127 | for (size_t i = 0; i < count; ++i) { |
Chris Manton | 5c26224 | 2014-10-14 22:00:32 -0700 | [diff] [blame] | 128 | osi_free(properties[i].val); |
Sharvil Nanavati | 3cf59ef | 2014-04-09 22:20:40 -0700 | [diff] [blame] | 129 | } |
| 130 | |
Chris Manton | 5c26224 | 2014-10-14 22:00:32 -0700 | [diff] [blame] | 131 | osi_free(properties); |
Sharvil Nanavati | 3cf59ef | 2014-04-09 22:20:40 -0700 | [diff] [blame] | 132 | } |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 133 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 134 | bool property_is_addr(const bt_property_t* property) { |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 135 | assert(property != NULL); |
| 136 | return property->type == BT_PROPERTY_BDADDR; |
| 137 | } |
| 138 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 139 | bool property_is_device_class(const bt_property_t* property) { |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 140 | assert(property != NULL); |
| 141 | return property->type == BT_PROPERTY_CLASS_OF_DEVICE; |
| 142 | } |
| 143 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 144 | bool property_is_device_type(const bt_property_t* property) { |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 145 | assert(property != NULL); |
| 146 | return property->type == BT_PROPERTY_TYPE_OF_DEVICE; |
| 147 | } |
| 148 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 149 | bool property_is_discovery_timeout(const bt_property_t* property) { |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 150 | assert(property != NULL); |
| 151 | return property->type == BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT; |
| 152 | } |
| 153 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 154 | bool property_is_name(const bt_property_t* property) { |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 155 | assert(property != NULL); |
| 156 | return property->type == BT_PROPERTY_BDNAME; |
| 157 | } |
| 158 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 159 | bool property_is_rssi(const bt_property_t* property) { |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 160 | assert(property != NULL); |
| 161 | return property->type == BT_PROPERTY_REMOTE_RSSI; |
| 162 | } |
| 163 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 164 | bool property_is_scan_mode(const bt_property_t* property) { |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 165 | assert(property != NULL); |
| 166 | return property->type == BT_PROPERTY_ADAPTER_SCAN_MODE; |
| 167 | } |
| 168 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 169 | bool property_is_uuids(const bt_property_t* property) { |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 170 | assert(property != NULL); |
| 171 | return property->type == BT_PROPERTY_UUIDS; |
| 172 | } |
| 173 | |
| 174 | // Convenience conversion methods to property values |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 175 | const bt_bdaddr_t* property_as_addr(const bt_property_t* property) { |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 176 | assert(property_is_addr(property)); |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 177 | return (const bt_bdaddr_t*)property->val; |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 178 | } |
| 179 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 180 | const bt_device_class_t* property_as_device_class( |
| 181 | const bt_property_t* property) { |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 182 | assert(property_is_device_class(property)); |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 183 | return (const bt_device_class_t*)property->val; |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 184 | } |
| 185 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 186 | bt_device_type_t property_as_device_type(const bt_property_t* property) { |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 187 | assert(property_is_device_type(property)); |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 188 | return *(const bt_device_type_t*)property->val; |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 189 | } |
| 190 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 191 | uint32_t property_as_discovery_timeout(const bt_property_t* property) { |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 192 | assert(property_is_discovery_timeout(property)); |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 193 | return *(const uint32_t*)property->val; |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 194 | } |
| 195 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 196 | const bt_bdname_t* property_as_name(const bt_property_t* property) { |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 197 | assert(property_is_name(property)); |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 198 | return (const bt_bdname_t*)property->val; |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 199 | } |
| 200 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 201 | int8_t property_as_rssi(const bt_property_t* property) { |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 202 | assert(property_is_rssi(property)); |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 203 | return *(const int8_t*)property->val; |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 204 | } |
| 205 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 206 | bt_scan_mode_t property_as_scan_mode(const bt_property_t* property) { |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 207 | assert(property_is_scan_mode(property)); |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 208 | return *(const bt_scan_mode_t*)property->val; |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 209 | } |
| 210 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 211 | const bt_uuid_t* property_as_uuids(const bt_property_t* property, |
| 212 | size_t* count) { |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 213 | assert(property_is_uuids(property)); |
| 214 | *count = sizeof(bt_uuid_t) / property->len; |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 215 | return (const bt_uuid_t*)property->val; |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 216 | } |
| 217 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame^] | 218 | static bt_property_t* property_new_(void* val, size_t len, |
| 219 | bt_property_type_t type) { |
| 220 | bt_property_t* property = |
| 221 | static_cast<bt_property_t*>(osi_calloc(sizeof(bt_property_t))); |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 222 | |
| 223 | property->val = osi_malloc(len); |
Chris Manton | 3252cf0 | 2015-01-08 10:47:59 -0800 | [diff] [blame] | 224 | memcpy(property->val, val, len); |
| 225 | |
| 226 | property->type = type; |
| 227 | property->len = len; |
| 228 | |
| 229 | return property; |
| 230 | } |