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 <arpa/inet.h> 20 #include <assert.h> 21 #include <string.h> 22 23 #include "btcore/include/device_class.h" 24 #include "osi/include/osi.h" 25 26 typedef struct _bt_device_class_t { 27 uint32_t unused : 2; // LSBs 28 uint32_t minor_device : 6; 29 uint32_t major_device : 5; 30 uint32_t major_service : 11; // MSBs 31 } __attribute__ ((__packed__)) _bt_device_class_t; 32 33 // Convenience to interpret raw device class bytes. 34 #define DC(x) ((_bt_device_class_t *)x) 35 36 // Ensure the internal device class implementation and public one 37 // have equal size. 38 COMPILE_ASSERT(sizeof(_bt_device_class_t) == sizeof(bt_device_class_t)); 39 40 // [Major Service Classes](https://www.bluetooth.org/en-us/specification/assigned-numbers/baseband) 41 enum { 42 DC_LIMITED_DISCOVERABLE_MODE = 0x0001, 43 DC_RESERVED14 = 0x0002, 44 DC_RESERVED15 = 0x0004, 45 DC_POSITIONING = 0x0008, 46 DC_NETWORKING = 0x0010, 47 DC_RENDERING = 0x0020, 48 DC_CAPTURING = 0x0040, 49 DC_OBJECT_TRANSFER = 0x0080, 50 DC_AUDIO = 0x0100, 51 DC_TELEPHONY = 0x0200, 52 DC_INFORMATION = 0x0400, 53 }; 54 55 static bool device_class_get_major_service_(const bt_device_class_t *dc, int bitmask); 56 static void device_class_clr_major_service_(bt_device_class_t *dc, int bitmask); 57 static void device_class_set_major_service_(bt_device_class_t *dc, int bitmask); 58 59 void device_class_from_stream(bt_device_class_t *dc, const uint8_t *data) { 60 assert(dc != NULL); 61 assert(data != NULL); 62 *dc = *(bt_device_class_t *)data; 63 } 64 65 int device_class_to_stream(const bt_device_class_t *dc, uint8_t *data, size_t len) { 66 assert(dc != NULL); 67 assert(data != NULL); 68 assert(len >= sizeof(bt_device_class_t)); 69 for (size_t i = 0; i < sizeof(bt_device_class_t); ++i) { 70 data[i] = dc->_[i]; 71 } 72 return sizeof(bt_device_class_t); 73 } 74 75 void device_class_from_int(bt_device_class_t *dc, int data) { 76 assert(dc != NULL); 77 assert(data != 0); 78 // Careful with endianess. 79 dc->_[0] = data & 0xff; 80 dc->_[1] = (data >> 8) & 0xff; 81 dc->_[2] = (data >> 16) & 0xff; 82 } 83 84 int device_class_to_int(const bt_device_class_t *dc) { 85 assert(dc != NULL); 86 // Careful with endianess. 87 return (int)(le32toh(*(int*)dc) & 0xffffff); 88 } 89 90 bool device_class_equals(const bt_device_class_t *p1, const bt_device_class_t *p2) { 91 assert(p1 != NULL); 92 assert(p2 != NULL); 93 return (memcmp(p1, p2, sizeof(bt_device_class_t)) == 0); 94 } 95 96 bool device_class_copy(bt_device_class_t *dest, const bt_device_class_t *src) { 97 assert(dest != NULL); 98 assert(src != NULL); 99 return (memcpy(dest, src, sizeof(bt_device_class_t)) == dest); 100 } 101 102 int device_class_get_major_device(const bt_device_class_t *dc) { 103 assert(dc != NULL); 104 return DC(dc)->major_device; 105 } 106 107 void device_class_set_major_device(bt_device_class_t *dc, int val) { 108 assert(dc != NULL); 109 DC(dc)->major_device = val; 110 } 111 112 int device_class_get_minor_device(const bt_device_class_t *dc) { 113 assert(dc != NULL); 114 return DC(dc)->minor_device; 115 } 116 117 void device_class_set_minor_device(bt_device_class_t *dc, int val) { 118 assert(dc != NULL); 119 DC(dc)->minor_device = val; 120 } 121 122 bool device_class_get_information(const bt_device_class_t *dc) { 123 assert(dc != NULL); 124 return device_class_get_major_service_(dc, DC_INFORMATION); 125 } 126 127 void device_class_set_information(bt_device_class_t *dc, bool set) { 128 assert(dc != NULL); 129 if (set) 130 device_class_set_major_service_(dc, DC_INFORMATION); 131 else 132 device_class_clr_major_service_(dc, DC_INFORMATION); 133 } 134 135 bool device_class_get_limited(const bt_device_class_t *dc) { 136 assert(dc != NULL); 137 return device_class_get_major_service_(dc, DC_LIMITED_DISCOVERABLE_MODE); 138 } 139 140 void device_class_set_limited(bt_device_class_t *dc, bool set) { 141 assert(dc != NULL); 142 if (set) 143 device_class_set_major_service_(dc, DC_LIMITED_DISCOVERABLE_MODE); 144 else 145 device_class_clr_major_service_(dc, DC_LIMITED_DISCOVERABLE_MODE); 146 } 147 148 static bool device_class_get_major_service_(const bt_device_class_t *dc, int bitmask) { 149 return (DC(dc)->major_service & bitmask); 150 } 151 152 static void device_class_clr_major_service_(bt_device_class_t *dc, int bitmask) { 153 DC(dc)->major_service &= ~bitmask; 154 } 155 156 static void device_class_set_major_service_(bt_device_class_t *dc, int bitmask) { 157 DC(dc)->major_service |= bitmask; 158 } 159