xref: /btstack/src/classic/goep_client.h (revision db806f4fd8e8d1df92cc0c13d105eac7ed7a8d1e)
1 /*
2  * Copyright (C) 2014 BlueKitchen GmbH
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holders nor the names of
14  *    contributors may be used to endorse or promote products derived
15  *    from this software without specific prior written permission.
16  * 4. Any redistribution, use, or modification is done solely for
17  *    personal benefit and not for any commercial purpose or for
18  *    monetary gain.
19  *
20  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24  * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * Please inquire about commercial licensing options at
34  * [email protected]
35  *
36  */
37 
38 /**
39  * @title GOEP Client
40  *
41  * Communicate with remote OBEX server - General Object Exchange
42  *
43  */
44 
45 #ifndef GOEP_CLIENT_H
46 #define GOEP_CLIENT_H
47 
48 #if defined __cplusplus
49 extern "C" {
50 #endif
51 
52 #include <stdlib.h>
53 #include <string.h>
54 
55 #include "btstack_defines.h"
56 #include "l2cap.h"
57 
58 typedef enum {
59     GOEP_CLIENT_INIT,
60     GOEP_CLIENT_W4_SDP,
61     GOEP_CLIENT_CONNECTED,
62 } goep_client_state_t;
63 
64 /* API_START */
65 
66 typedef struct {
67     btstack_linked_item_t item;
68 
69     uint16_t         cid;
70 
71     goep_client_state_t     state;
72     bd_addr_t        bd_addr;
73     uint16_t         uuid;
74     hci_con_handle_t con_handle;
75     uint8_t          incoming;
76 
77     btstack_packet_handler_t client_handler;
78     btstack_context_callback_registration_t sdp_query_request;
79 
80     uint8_t          rfcomm_port;
81     uint16_t         l2cap_psm;
82     uint16_t         bearer_cid;
83     uint16_t         bearer_mtu;
84 
85     uint16_t         record_index;
86 
87     // cached higher layer information PBAP + MAP
88     uint32_t         profile_supported_features;
89     uint8_t          map_mas_instance_id;
90     uint8_t          map_supported_message_types;
91 
92     // needed to select one of multiple MAS Instances
93     struct {
94         uint32_t supported_features;
95         uint8_t  instance_id;
96         uint8_t  supported_message_types;
97         uint8_t  rfcomm_port;
98 #ifdef ENABLE_GOEP_L2CAP
99         uint16_t l2cap_psm;
100 #endif
101     } mas_info;
102 
103     uint8_t          obex_opcode;
104     uint32_t         obex_connection_id;
105     int              obex_connection_id_set;
106 
107 #ifdef ENABLE_GOEP_L2CAP
108     l2cap_ertm_config_t ertm_config;
109     uint16_t            ertm_buffer_size;
110     uint8_t           * ertm_buffer;
111 #endif
112 } goep_client_t;
113 
114 
115 // remote does not expose PBAP features in SDP record
116 #define PBAP_FEATURES_NOT_PRESENT ((uint32_t) -1)
117 #define MAP_FEATURES_NOT_PRESENT ((uint32_t) -1)
118 #define PROFILE_FEATURES_NOT_PRESENT ((uint32_t) -1)
119 
120 /**
121  * Setup GOEP Client
122  */
123 void goep_client_init(void);
124 
125 /**
126  * @brief Connect to a GEOP server with specified UUID on a remote device.
127  * @param goep_client
128  * @param l2cap_ertm_config
129  * @param l2cap_ertm_buffer_size
130  * @param l2cap_ertm_buffer
131  * @param handler
132  * @param addr
133  * @param uuid
134  * @param instance_id e.g. used to connect to different MAP Access Servers, default: 0
135  * @param out_cid
136  * @return
137  */
138 uint8_t
139 goep_client_connect(goep_client_t *goep_client, l2cap_ertm_config_t *l2cap_ertm_config, uint8_t *l2cap_ertm_buffer,
140                     uint16_t l2cap_ertm_buffer_size, btstack_packet_handler_t handler, bd_addr_t addr, uint16_t uuid,
141                     uint8_t instance_id, uint16_t *out_cid);
142 
143 /**
144  * @brief Connect to a GEOP server over L2CAP with specified PSM on a remote device.
145  * @note In contrast to goep_client_connect which searches for a OBEX service with a given UUID, this
146  *       function only supports GOEP v2.0 (L2CAP) to a specified L2CAP PSM
147  * @param goep_client
148  * @param l2cap_ertm_config
149  * @param l2cap_ertm_buffer_size
150  * @param l2cap_ertm_buffer
151  * @param handler
152  * @param addr
153  * @param l2cap_psm
154  * @param out_cid
155  * @return
156  */
157 uint8_t
158 goep_client_connect_l2cap(goep_client_t *goep_client, l2cap_ertm_config_t *l2cap_ertm_config, uint8_t *l2cap_ertm_buffer,
159                     uint16_t l2cap_ertm_buffer_size, btstack_packet_handler_t handler, bd_addr_t addr, uint16_t l2cap_psm,
160                     uint16_t *out_cid);
161 
162 /**
163  * @brief Disconnects GOEP connection with given identifier.
164  * @param goep_cid
165  * @return status
166  */
167 uint8_t goep_client_disconnect(uint16_t goep_cid);
168 
169 /**
170  * @brief Request emission of GOEP_SUBEVENT_CAN_SEND_NOW as soon as possible
171  * @note GOEP_SUBEVENT_CAN_SEND_NOW might be emitted during call to this function
172  *       so packet handler should be ready to handle it
173  * @param goep_cid
174  */
175 void goep_client_request_can_send_now(uint16_t goep_cid);
176 
177 /**
178  * @brief Get Opcode from last created request, needed for parsing of OBEX response packet
179  * @param goep_cid
180  * @return opcode
181  */
182 uint8_t goep_client_get_request_opcode(uint16_t goep_cid);
183 
184 /**
185  * @brief Get PBAP Supported Features found in SDP record during connect
186  */
187 uint32_t goep_client_get_pbap_supported_features(uint16_t goep_cid);
188 
189 /**
190  * @brief Get MAP Supported Features found in SDP record during connect
191  */
192 uint32_t goep_client_get_map_supported_features(uint16_t goep_cid);
193 
194 /**
195  * @brief Get MAP MAS Instance ID found in SDP record during connect
196  */
197 uint8_t goep_client_get_map_mas_instance_id(uint16_t goep_cid);
198 
199 /**
200  * @brief Get MAP MAS Supported Message Types found in SDP record during connect
201  */
202 uint8_t goep_client_get_map_supported_message_types(uint16_t goep_cid);
203 
204 /**
205  * @brief Check if GOEP 2.0 or higher features can be used
206  * @return true if GOEP Version 2.0 or higher
207  */
208 bool goep_client_version_20_or_higher(uint16_t goep_cid);
209 
210 /**
211  * @brief Set Connection ID used for newly created requests
212  * @param goep_cid
213  */
214 void goep_client_set_connection_id(uint16_t goep_cid, uint32_t connection_id);
215 
216 /**
217  * @brief Start Connect request
218  * @param goep_cid
219  * @param obex_version_number
220  * @param flags
221  * @param maximum_obex_packet_length
222  */
223 void goep_client_request_create_connect(uint16_t goep_cid, uint8_t obex_version_number, uint8_t flags, uint16_t maximum_obex_packet_length);
224 
225 /**
226  * @brief Start Disconnect request
227  * @param goep_cid
228  */
229 void goep_client_request_create_disconnect(uint16_t goep_cid);
230 
231 /**
232  * @brief Create Get request
233  * @param goep_cid
234  */
235 void goep_client_request_create_get(uint16_t goep_cid);
236 
237 /**
238  * @brief Create Abort request
239  * @param goep_cid
240  */
241 void goep_client_request_create_abort(uint16_t goep_cid);
242 
243 /**
244  * @brief Start Set Path request
245  * @param goep_cid
246  */
247 void goep_client_request_create_set_path(uint16_t goep_cid, uint8_t flags);
248 
249 /**
250  * @brief Create Put request
251  * @param goep_cid
252  */
253 void goep_client_request_create_put(uint16_t goep_cid);
254 
255 /**
256  * @brief Get max size of body data that can be added to current response with goep_client_body_add_static
257  * @param goep_cid
258  * @param data
259  * @param length
260  * @return size in bytes or 0
261  */
262 uint16_t goep_client_request_get_max_body_size(uint16_t goep_cid);
263 
264 /**
265  * @brief Add SRM Enable
266  * @param goep_cid
267  */
268 void goep_client_header_add_srm_enable(uint16_t goep_cid);
269 
270 /**
271  * @brief Add header with single byte value (8 bit)
272  * @param goep_cid
273  * @param header_type
274  * @param value
275  */
276 void goep_client_header_add_byte(uint16_t goep_cid, uint8_t header_type, uint8_t value);
277 
278 /**
279  * @brief Add header with word value (32 bit)
280  * @param goep_cid
281  * @param header_type
282  * @param value
283  */
284 void goep_client_header_add_word(uint16_t goep_cid, uint8_t header_type, uint32_t value);
285 
286 /**
287  * @brief Add header with variable size
288  * @param goep_cid
289  * @param header_type
290  * @param header_data
291  * @param header_data_length
292  */
293 void goep_client_header_add_variable(uint16_t goep_cid, uint8_t header_type, const uint8_t * header_data, uint16_t header_data_length);
294 
295 /**
296  * @brief Add name header to current request
297  * @param goep_cid
298  * @param name
299  */
300 void goep_client_header_add_name(uint16_t goep_cid, const char * name);
301 
302 /**
303  * @brief Add name header to current request
304  * @param goep_cid
305  * @param name
306  * @param name_len
307  */
308 void goep_client_header_add_name_prefix(uint16_t goep_cid, const char * name, uint16_t name_len);
309 
310 /**
311  * @brief Add string encoded as unicode to current request
312  * @param goep_cid
313  * @param name
314  * @param name_len
315  */
316 void goep_client_header_add_unicode_prefix(uint16_t goep_cid, uint8_t header_id, const char * name, uint16_t name_len);
317 
318 /**
319  * @brief Add target header to current request
320  * @param goep_cid
321  * @param target
322  * @param length of target
323  */
324 void goep_client_header_add_target(uint16_t goep_cid, const uint8_t * target, uint16_t length);
325 
326 /**
327  * @brief Add type header to current request
328  * @param goep_cid
329  * @param type
330  */
331 void goep_client_header_add_type(uint16_t goep_cid, const char * type);
332 
333 /**
334  * @brief Add count header to current request
335  * @param goep_cid
336  * @param count
337  */
338 void goep_client_header_add_count(uint16_t goep_cid, uint32_t count);
339 
340 /**
341  * @brief Add length header to current request
342  * @param goep_cid
343  * @param length
344  */
345 void goep_client_header_add_length(uint16_t goep_cid, uint32_t length);
346 
347 /**
348  * @brief Add application parameters header to current request
349  * @param goep_cid
350  * @param data
351  * @param lenght of application parameters
352  */
353 void goep_client_header_add_application_parameters(uint16_t goep_cid, const uint8_t * data, uint16_t length);
354 
355 /**
356  * @brief Add application parameters header to current request
357  * @param goep_cid
358  * @param data
359  * @param lenght of challenge response
360  */
361 void goep_client_header_add_challenge_response(uint16_t goep_cid, const uint8_t * data, uint16_t length);
362 
363 /**
364  * @brief Add body
365  * @param goep_cid
366  * @param data
367  * @param lenght
368  */
369 void goep_client_body_add_static(uint16_t goep_cid, const uint8_t * data, uint32_t length);
370 
371 /**
372  * @brief Query remaining buffer size
373  * @param goep_cid
374  * @return size
375  */
376 uint16_t goep_client_body_get_outgoing_buffer_len(uint16_t goep_cid);
377 
378 /**
379  * @brief Add body
380  * @param goep_cid
381  * @param data
382  * @param length
383  * @param ret_length
384  */
385 void goep_client_body_fillup_static(uint16_t goep_cid, const uint8_t * data, uint32_t length, uint32_t * ret_length);
386 
387 /**
388  * @brief Execute prepared request
389  * @param goep_cid
390  * @param daa
391  */
392 int goep_client_execute(uint16_t goep_cid);
393 
394 /**
395  * @brief Execute prepared request with final bit
396  * @param goep_cid
397  * @param final
398  */
399 int goep_client_execute_with_final_bit(uint16_t goep_cid, bool final);
400 
401 /**
402  * @brief De-Init GOEP Client
403  */
404 void goep_client_deinit(void);
405 
406 /* API_END */
407 
408 // int goep_client_body_add_dynamic(uint16_t goep_cid, uint32_t length, void (*data_callback)(uint32_t offset, uint8_t * buffer, uint32_t len));
409 
410 #if defined __cplusplus
411 }
412 #endif
413 #endif
414 
415