1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef SDP_UTIL_H
17 #define SDP_UTIL_H
18 
19 #include "sdp.h"
20 
21 #include <stdbool.h>
22 #include <stdint.h>
23 #include <stdlib.h>
24 
25 #include "packet.h"
26 
27 #ifndef NO_SANITIZE
28 #ifdef __has_attribute
29 #if __has_attribute(no_sanitize)
30 #define NO_SANITIZE(type) __attribute__((no_sanitize(type)))
31 #endif
32 #endif
33 #endif
34 
35 #ifndef NO_SANITIZE
36 #define NO_SANITIZE(type)
37 #endif
38 
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42 
43 /// The PSM that SDP uses.
44 #define SDP_PSM 0x0001
45 /// Max reserved ServiceRecordHandle
46 #define SDP_MAX_RESERVED_RECORD_HANDLE 0xFFFF
47 /// The maximum number of attributes in each record.
48 #define SDP_MAX_ATTRIBUTE_COUNT 20
49 /// The maximum length, in bytes, of an attribute.
50 #define SDP_MAX_ATTRIBUTE_LEN 400
51 /// The maximum number of UUID in the sequence.
52 #define SDP_MAX_UUID_COUNT 12
53 /// The maximum number of record handles.
54 #define SDP_MAX_RECORD_HANDLE_COUNT 60
55 /// The size of a scratchpad buffer, in bytes, for storing the response to an attribute request.
56 #define SDP_MAX_LIST_BYTE_COUNT 4096
57 /// The maximum number of parameters in an SDP protocol element.
58 #define SDP_MAX_PROTOCOL_PARAMS 4
59 /// Other attribute count
60 #define SDP_ATTRIBUTE_COUNT 8
61 /// Other sequence attribute count
62 #define SDP_SEQUENCE_ATTRIBUTE_COUNT 5
63 /// The number of SdpService arrays
64 #define SDP_SERVICE_ARRAY_NUMBER 60
65 /// The mtu size for the L2CAP configuration.
66 #define SDP_MTU_SIZE 672
67 /// The maximum attribute byte count
68 #define SDP_MAX_ATTRIBUTE_BYTE_COUNT 651
69 /// Header length for request and response
70 #define SDP_PDU_HEADER_LENGTH 5
71 /// Header and tail length
72 #define SDP_PACKET_HEADER_AND_TAIL_LENGTH 21
73 /// ContinuationState
74 #define SDP_MAX_CONTINUATION_LEN 16
75 /// Wait time for connect
76 #define SDP_CONNECT_WAIT_TIME 4000
77 /// Timeout (ms)
78 #define SDP_CONNECT_TIMEOUT 40000
79 
80 #define SDP_STATE_IDLE 0
81 #define SDP_STATE_CONN_SETUP 1
82 #define SDP_STATE_CFG_REQ_SETUP 2
83 #define SDP_STATE_CFG_RSP_SETUP 3
84 #define SDP_STATE_CONNECTED 4
85 #define SDP_STATE_DISCONNECT 5
86 #define SDP_STATE_TIMEOUT 6
87 
88 #define SDP_PACKET_WAIT 0
89 #define SDP_PACKET_SEND 1
90 #define SDP_PACKET_SEND_FRAGMENT 2
91 
92 /// SDP response error code
93 #define SDP_INVALID_VERSION 0x0001       /// Invalid/unsupported SDP version
94 #define SDP_INVALID_SERV_REC_HDL 0x0002  /// Invalid Service Record Handle
95 #define SDP_INVALID_REQ_SYNTAX 0x0003    /// Invalid request syntax
96 #define SDP_INVALID_PDU_SIZE 0x0004      /// Invalid PDU Size
97 #define SDP_INVALID_CONT_STATE 0x0005    /// Invalid Continuation State
98 #define SDP_NO_RESOURCES 0x0006          /// Insufficient Resources to satisfy Request
99 
100 #define SDP_PROTOCOL_DESCRIPTOR_LIST_MAX 4
101 #define SDP_PROTOCOL_DESCRIPTOR_MAX 4
102 #define SDP_LANGUAGE_ATTRIBUTE_MAX 5
103 #define SDP_LANGUAGE_ATTRIBUTE_LENGTH 9
104 
105 #define SDP_BLUETOOTH_ADDRESS_LENGTH 6
106 #define SDP_SERVICE_RECORD_HANDLE_BYTE 4
107 #define SDP_DESCRIPTOR_SIZE_BIT 3
108 #define SDP_SERVICE_RECORD_OTHER 7
109 
110 #define SDP_PACKET_TAIL_ONE_BYTE 1
111 #define SDP_PACKET_TAIL_TWO_BYTE 2
112 #define SDP_PACKET_TAIL_THREE_BYTE 3
113 
114 #define SDP_UINT8_LENGTH 1
115 #define SDP_UINT16_LENGTH 2
116 #define SDP_UINT32_LENGTH 4
117 #define SDP_UINT64_LENGTH 8
118 #define SDP_UINT128_LENGTH 16
119 
120 #define SDP_INT8_LENGTH 1
121 #define SDP_INT16_LENGTH 2
122 #define SDP_INT32_LENGTH 4
123 
124 #define SDP_UUID16_LENGTH 2
125 #define SDP_UUID32_LENGTH 4
126 #define SDP_UUID128_LENGTH 16
127 
128 typedef enum {
129     DE_TYPE_NIL = 0,
130     DE_TYPE_UINT,
131     DE_TYPE_INT,
132     DE_TYPE_UUID,
133     DE_TYPE_STRING,
134     DE_TYPE_BOOL,
135     DE_TYPE_DES,
136     DE_TYPE_DEA,
137     DE_TYPE_URL
138 } SdpDescriptorType;
139 
140 typedef enum {
141     DE_SIZE_8 = 0,
142     DE_SIZE_16,
143     DE_SIZE_32,
144     DE_SIZE_64,
145     DE_SIZE_128,
146     DE_SIZE_VAR_8,
147     DE_SIZE_VAR_16,
148     DE_SIZE_VAR_32
149 } SdpDescriptorSize;
150 
151 typedef enum {
152     SDP_INVALID = 0x00,
153     SDP_ERROR_RESPONSE = 0x01,
154     SDP_SERVICE_SEARCH_REQUEST,
155     SDP_SERVICE_SEARCH_RESPONSE,
156     SDP_SERVICE_ATTRIBUTE_REQUEST,
157     SDP_SERVICE_ATTRIBUTE_RESPONSE,
158     SDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST,
159     SDP_SERVICE_SEARCH_ATTRIBUTE_RESPONSE
160 } SdpPduId;
161 
162 typedef union {
163     void (*ServiceSearchCb)(const BtAddr *addr, const uint32_t *handleArray, uint16_t handleNum, void *context);
164     void (*ServiceAttributeCb)(const BtAddr *addr, const SdpService *service, void *context);
165     void (*ServiceSearchAttributeCb)(
166         const BtAddr *addr, const SdpService *serviceArray, uint16_t serviceNum, void *context);
167 } SdpServiceCallback;
168 
169 typedef struct {
170     BtAddr addr;
171     SdpPduId pduId;
172     uint16_t transactionId;
173     bool resentFlag;
174     uint8_t packetState;
175     Packet *packet;
176     Packet *assemblePacket;
177     SdpServiceCallback callback;
178     void *context;
179 } SdpClientRequest;
180 
181 void SdpSetEnableState();
182 void SdpSetDisableState();
183 bool SdpGetEnableState();
184 void SdpReverseForBigEndian(const uint8_t *src, uint8_t *dst, int length);
185 uint16_t SdpAddAttributeForUuid(uint8_t *buffer, uint16_t offset, const BtUuid *uuid);
186 uint16_t SdpGetLengthFromType(const uint8_t *buffer, uint8_t type, uint32_t *length);
187 uint16_t SdpGetUuid(uint8_t *buffer, BtUuid *uuid);
188 
189 #if defined __cplusplus
190 }
191 #endif
192 
193 #endif  // SDP_UTIL_H
194