OSDN Git Service

Treat empty/truncated GATT cache as error am: 1f656f15b1 am: 774defe11b
[android-x86/system-bt.git] / btcore / src / device_class.c
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 }