xref: /btstack/src/classic/goep_client.h (revision ced70f9bfeafe291ec597a3a9cc862e39e0da3ce)
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 Connect to a GEOP server with specified UUID on a remote device.
164  * @note This functions uses a single goep_client_t instance and only allows for a single goep connection
165  *       Please use goep_client_connect instead
166  * @param handler
167  * @param addr
168  * @param uuid
169  * @param out_cid to use for further commands
170  * @result status
171 */
172 uint8_t goep_client_create_connection(btstack_packet_handler_t handler, bd_addr_t addr, uint16_t uuid, uint16_t * out_cid);
173 
174 /**
175  * @brief Disconnects GOEP connection with given identifier.
176  * @param goep_cid
177  * @return status
178  */
179 uint8_t goep_client_disconnect(uint16_t goep_cid);
180 
181 /**
182  * @brief Request emission of GOEP_SUBEVENT_CAN_SEND_NOW as soon as possible
183  * @note GOEP_SUBEVENT_CAN_SEND_NOW might be emitted during call to this function
184  *       so packet handler should be ready to handle it
185  * @param goep_cid
186  */
187 void goep_client_request_can_send_now(uint16_t goep_cid);
188 
189 /**
190  * @brief Get Opcode from last created request, needed for parsing of OBEX response packet
191  * @param goep_cid
192  * @return opcode
193  */
194 uint8_t goep_client_get_request_opcode(uint16_t goep_cid);
195 
196 /**
197  * @brief Get PBAP Supported Features found in SDP record during connect
198  */
199 uint32_t goep_client_get_pbap_supported_features(uint16_t goep_cid);
200 
201 /**
202  * @brief Get MAP Supported Features found in SDP record during connect
203  */
204 uint32_t goep_client_get_map_supported_features(uint16_t goep_cid);
205 
206 /**
207  * @brief Get MAP MAS Instance ID found in SDP record during connect
208  */
209 uint8_t goep_client_get_map_mas_instance_id(uint16_t goep_cid);
210 
211 /**
212  * @brief Get MAP MAS Supported Message Types found in SDP record during connect
213  */
214 uint8_t goep_client_get_map_supported_message_types(uint16_t goep_cid);
215 
216 /**
217  * @brief Check if GOEP 2.0 or higher features can be used
218  * @return true if GOEP Version 2.0 or higher
219  */
220 bool goep_client_version_20_or_higher(uint16_t goep_cid);
221 
222 /**
223  * @brief Set Connection ID used for newly created requests
224  * @param goep_cid
225  */
226 void goep_client_set_connection_id(uint16_t goep_cid, uint32_t connection_id);
227 
228 /**
229  * @brief Start Connect request
230  * @param goep_cid
231  * @param obex_version_number
232  * @param flags
233  * @param maximum_obex_packet_length
234  */
235 void goep_client_request_create_connect(uint16_t goep_cid, uint8_t obex_version_number, uint8_t flags, uint16_t maximum_obex_packet_length);
236 
237 /**
238  * @brief Start Disconnect request
239  * @param goep_cid
240  */
241 void goep_client_request_create_disconnect(uint16_t goep_cid);
242 
243 /**
244  * @brief Create Get request
245  * @param goep_cid
246  */
247 void goep_client_request_create_get(uint16_t goep_cid);
248 
249 /**
250  * @brief Create Abort request
251  * @param goep_cid
252  */
253 void goep_client_request_create_abort(uint16_t goep_cid);
254 
255 /**
256  * @brief Start Set Path request
257  * @param goep_cid
258  */
259 void goep_client_request_create_set_path(uint16_t goep_cid, uint8_t flags);
260 
261 /**
262  * @brief Create Put request
263  * @param goep_cid
264  */
265 void goep_client_request_create_put(uint16_t goep_cid);
266 
267 /**
268  * @brief Get max size of body data that can be added to current response with goep_client_body_add_static
269  * @param goep_cid
270  * @param data
271  * @param length
272  * @return size in bytes or 0
273  */
274 uint16_t goep_client_request_get_max_body_size(uint16_t goep_cid);
275 
276 /**
277  * @brief Add SRM Enable
278  * @param goep_cid
279  */
280 void goep_client_header_add_srm_enable(uint16_t goep_cid);
281 
282 /**
283  * @brief Add header with single byte value (8 bit)
284  * @param goep_cid
285  * @param header_type
286  * @param value
287  */
288 void goep_client_header_add_byte(uint16_t goep_cid, uint8_t header_type, uint8_t value);
289 
290 /**
291  * @brief Add header with word value (32 bit)
292  * @param goep_cid
293  * @param header_type
294  * @param value
295  */
296 void goep_client_header_add_word(uint16_t goep_cid, uint8_t header_type, uint32_t value);
297 
298 /**
299  * @brief Add header with variable size
300  * @param goep_cid
301  * @param header_type
302  * @param header_data
303  * @param header_data_length
304  */
305 void goep_client_header_add_variable(uint16_t goep_cid, uint8_t header_type, const uint8_t * header_data, uint16_t header_data_length);
306 
307 /**
308  * @brief Add name header to current request
309  * @param goep_cid
310  * @param name
311  */
312 void goep_client_header_add_name(uint16_t goep_cid, const char * name);
313 
314 /**
315  * @brief Add name header to current request
316  * @param goep_cid
317  * @param name
318  * @param name_len
319  */
320 void goep_client_header_add_name_prefix(uint16_t goep_cid, const char * name, uint16_t name_len);
321 
322 /**
323  * @brief Add string encoded as unicode to current request
324  * @param goep_cid
325  * @param name
326  * @param name_len
327  */
328 void goep_client_header_add_unicode_prefix(uint16_t goep_cid, uint8_t header_id, const char * name, uint16_t name_len);
329 
330 /**
331  * @brief Add target header to current request
332  * @param goep_cid
333  * @param target
334  * @param length of target
335  */
336 void goep_client_header_add_target(uint16_t goep_cid, const uint8_t * target, uint16_t length);
337 
338 /**
339  * @brief Add type header to current request
340  * @param goep_cid
341  * @param type
342  */
343 void goep_client_header_add_type(uint16_t goep_cid, const char * type);
344 
345 /**
346  * @brief Add count header to current request
347  * @param goep_cid
348  * @param count
349  */
350 void goep_client_header_add_count(uint16_t goep_cid, uint32_t count);
351 
352 /**
353  * @brief Add length header to current request
354  * @param goep_cid
355  * @param length
356  */
357 void goep_client_header_add_length(uint16_t goep_cid, uint32_t length);
358 
359 /**
360  * @brief Add application parameters header to current request
361  * @param goep_cid
362  * @param data
363  * @param lenght of application parameters
364  */
365 void goep_client_header_add_application_parameters(uint16_t goep_cid, const uint8_t * data, uint16_t length);
366 
367 /**
368  * @brief Add application parameters header to current request
369  * @param goep_cid
370  * @param data
371  * @param lenght of challenge response
372  */
373 void goep_client_header_add_challenge_response(uint16_t goep_cid, const uint8_t * data, uint16_t length);
374 
375 /**
376  * @brief Add body
377  * @param goep_cid
378  * @param data
379  * @param lenght
380  */
381 void goep_client_body_add_static(uint16_t goep_cid, const uint8_t * data, uint32_t length);
382 
383 /**
384  * @brief Query remaining buffer size
385  * @param goep_cid
386  * @return size
387  */
388 uint16_t goep_client_body_get_outgoing_buffer_len(uint16_t goep_cid);
389 
390 /**
391  * @brief Add body
392  * @param goep_cid
393  * @param data
394  * @param length
395  * @param ret_length
396  */
397 void goep_client_body_fillup_static(uint16_t goep_cid, const uint8_t * data, uint32_t length, uint32_t * ret_length);
398 
399 /**
400  * @brief Execute prepared request
401  * @param goep_cid
402  * @param daa
403  */
404 int goep_client_execute(uint16_t goep_cid);
405 
406 /**
407  * @brief Execute prepared request with final bit
408  * @param goep_cid
409  * @param final
410  */
411 int goep_client_execute_with_final_bit(uint16_t goep_cid, bool final);
412 
413 /**
414  * @brief De-Init GOEP Client
415  */
416 void goep_client_deinit(void);
417 
418 /* API_END */
419 
420 // 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));
421 
422 #if defined __cplusplus
423 }
424 #endif
425 #endif
426 
427