xref: /btstack/src/classic/goep_client.h (revision d38efbba5c7565403822c9c38ce512c8d5cc1815)
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     uint16_t         map_version;
92 
93     // needed to select one of multiple MAS Instances
94     struct {
95         uint32_t supported_features;
96         uint8_t  instance_id;
97         uint8_t  supported_message_types;
98         uint8_t  rfcomm_port;
99         uint16_t version;
100 #ifdef ENABLE_GOEP_L2CAP
101         uint16_t l2cap_psm;
102 #endif
103     } mas_info;
104 
105     uint8_t          obex_opcode;
106     uint32_t         obex_connection_id;
107     int              obex_connection_id_set;
108 
109 #ifdef ENABLE_GOEP_L2CAP
110     l2cap_ertm_config_t ertm_config;
111     uint16_t            ertm_buffer_size;
112     uint8_t           * ertm_buffer;
113 #endif
114 } goep_client_t;
115 
116 
117 // remote does not expose PBAP features in SDP record
118 #define PBAP_FEATURES_NOT_PRESENT ((uint32_t) -1)
119 #define MAP_FEATURES_NOT_PRESENT ((uint32_t) -1)
120 #define PROFILE_FEATURES_NOT_PRESENT ((uint32_t) -1)
121 
122 /**
123  * Setup GOEP Client
124  */
125 void goep_client_init(void);
126 
127 /**
128  * @brief Connect to a GEOP server with specified UUID on a remote device.
129  * @param goep_client
130  * @param l2cap_ertm_config
131  * @param l2cap_ertm_buffer_size
132  * @param l2cap_ertm_buffer
133  * @param handler
134  * @param addr
135  * @param uuid
136  * @param instance_id e.g. used to connect to different MAP Access Servers, default: 0
137  * @param out_cid
138  * @return
139  */
140 uint8_t
141 goep_client_connect(goep_client_t *goep_client, l2cap_ertm_config_t *l2cap_ertm_config, uint8_t *l2cap_ertm_buffer,
142                     uint16_t l2cap_ertm_buffer_size, btstack_packet_handler_t handler, bd_addr_t addr, uint16_t uuid,
143                     uint8_t instance_id, uint16_t *out_cid);
144 
145 /**
146  * @brief Connect to a GEOP server over L2CAP with specified PSM on a remote device.
147  * @note In contrast to goep_client_connect which searches for a OBEX service with a given UUID, this
148  *       function only supports GOEP v2.0 (L2CAP) to a specified L2CAP PSM
149  * @param goep_client
150  * @param l2cap_ertm_config
151  * @param l2cap_ertm_buffer_size
152  * @param l2cap_ertm_buffer
153  * @param handler
154  * @param addr
155  * @param l2cap_psm
156  * @param out_cid
157  * @return
158  */
159 uint8_t
160 goep_client_connect_l2cap(goep_client_t *goep_client, l2cap_ertm_config_t *l2cap_ertm_config, uint8_t *l2cap_ertm_buffer,
161                     uint16_t l2cap_ertm_buffer_size, btstack_packet_handler_t handler, bd_addr_t addr, uint16_t l2cap_psm,
162                     uint16_t *out_cid);
163 
164 /**
165  * @brief Disconnects GOEP connection with given identifier.
166  * @param goep_cid
167  * @return status
168  */
169 uint8_t goep_client_disconnect(uint16_t goep_cid);
170 
171 /**
172  * @brief Request emission of GOEP_SUBEVENT_CAN_SEND_NOW as soon as possible
173  * @note GOEP_SUBEVENT_CAN_SEND_NOW might be emitted during call to this function
174  *       so packet handler should be ready to handle it
175  * @param goep_cid
176  */
177 void goep_client_request_can_send_now(uint16_t goep_cid);
178 
179 /**
180  * @brief Get Opcode from last created request, needed for parsing of OBEX response packet
181  * @param goep_cid
182  * @return opcode
183  */
184 uint8_t goep_client_get_request_opcode(uint16_t goep_cid);
185 
186 /**
187  * @brief Get PBAP Supported Features found in SDP record during connect
188  */
189 uint32_t goep_client_get_pbap_supported_features(uint16_t goep_cid);
190 
191 /**
192  * @brief Get MAP Supported Features found in SDP record during connect
193  */
194 uint32_t goep_client_get_map_supported_features(uint16_t goep_cid);
195 
196 /**
197  * @brief Get MAP MAS Instance ID found in SDP record during connect
198  */
199 uint8_t goep_client_get_map_mas_instance_id(uint16_t goep_cid);
200 
201 /**
202  * @brief Get MAP MAS Supported Message Types found in SDP record during connect
203  */
204 uint8_t goep_client_get_map_supported_message_types(uint16_t goep_cid);
205 
206 /**
207  * @brief Check if GOEP 2.0 or higher features can be used
208  * @return true if GOEP Version 2.0 or higher
209  */
210 bool goep_client_version_20_or_higher(uint16_t goep_cid);
211 
212 /**
213  * @brief Set Connection ID used for newly created requests
214  * @param goep_cid
215  */
216 void goep_client_set_connection_id(uint16_t goep_cid, uint32_t connection_id);
217 
218 /**
219  * @brief Start Connect request
220  * @param goep_cid
221  * @param obex_version_number
222  * @param flags
223  * @param maximum_obex_packet_length
224  */
225 void goep_client_request_create_connect(uint16_t goep_cid, uint8_t obex_version_number, uint8_t flags, uint16_t maximum_obex_packet_length);
226 
227 /**
228  * @brief Start Disconnect request
229  * @param goep_cid
230  */
231 void goep_client_request_create_disconnect(uint16_t goep_cid);
232 
233 /**
234  * @brief Create Get request
235  * @param goep_cid
236  */
237 void goep_client_request_create_get(uint16_t goep_cid);
238 
239 /**
240  * @brief Create Abort request
241  * @param goep_cid
242  */
243 void goep_client_request_create_abort(uint16_t goep_cid);
244 
245 /**
246  * @brief Start Set Path request
247  * @param goep_cid
248  */
249 void goep_client_request_create_set_path(uint16_t goep_cid, uint8_t flags);
250 
251 /**
252  * @brief Create Put request
253  * @param goep_cid
254  */
255 void goep_client_request_create_put(uint16_t goep_cid);
256 
257 /**
258  * @brief Get max size of body data that can be added to current response with goep_client_body_add_static
259  * @param goep_cid
260  * @param data
261  * @param length
262  * @return size in bytes or 0
263  */
264 uint16_t goep_client_request_get_max_body_size(uint16_t goep_cid);
265 
266 /**
267  * @brief Add SRM Enable
268  * @param goep_cid
269  */
270 void goep_client_header_add_srm_enable(uint16_t goep_cid);
271 
272 /**
273  * @brief Add header with single byte value (8 bit)
274  * @param goep_cid
275  * @param header_type
276  * @param value
277  */
278 void goep_client_header_add_byte(uint16_t goep_cid, uint8_t header_type, uint8_t value);
279 
280 /**
281  * @brief Add header with word value (32 bit)
282  * @param goep_cid
283  * @param header_type
284  * @param value
285  */
286 void goep_client_header_add_word(uint16_t goep_cid, uint8_t header_type, uint32_t value);
287 
288 /**
289  * @brief Add header with variable size
290  * @param goep_cid
291  * @param header_type
292  * @param header_data
293  * @param header_data_length
294  */
295 void goep_client_header_add_variable(uint16_t goep_cid, uint8_t header_type, const uint8_t * header_data, uint16_t header_data_length);
296 
297 /**
298  * @brief Add name header to current request
299  * @param goep_cid
300  * @param name
301  */
302 void goep_client_header_add_name(uint16_t goep_cid, const char * name);
303 
304 /**
305  * @brief Add name header to current request
306  * @param goep_cid
307  * @param name
308  * @param name_len
309  */
310 void goep_client_header_add_name_prefix(uint16_t goep_cid, const char * name, uint16_t name_len);
311 
312 /**
313  * @brief Add string encoded as unicode to current request
314  * @param goep_cid
315  * @param name
316  * @param name_len
317  */
318 void goep_client_header_add_unicode_prefix(uint16_t goep_cid, uint8_t header_id, const char * name, uint16_t name_len);
319 
320 /**
321  * @brief Add target header to current request
322  * @param goep_cid
323  * @param target
324  * @param length of target
325  */
326 void goep_client_header_add_target(uint16_t goep_cid, const uint8_t * target, uint16_t length);
327 
328 /**
329  * @brief Add type header to current request
330  * @param goep_cid
331  * @param type
332  */
333 void goep_client_header_add_type(uint16_t goep_cid, const char * type);
334 
335 /**
336  * @brief Add count header to current request
337  * @param goep_cid
338  * @param count
339  */
340 void goep_client_header_add_count(uint16_t goep_cid, uint32_t count);
341 
342 /**
343  * @brief Add length header to current request
344  * @param goep_cid
345  * @param length
346  */
347 void goep_client_header_add_length(uint16_t goep_cid, uint32_t length);
348 
349 /**
350  * @brief Add application parameters header to current request
351  * @param goep_cid
352  * @param data
353  * @param lenght of application parameters
354  */
355 void goep_client_header_add_application_parameters(uint16_t goep_cid, const uint8_t * data, uint16_t length);
356 
357 /**
358  * @brief Add application parameters header to current request
359  * @param goep_cid
360  * @param data
361  * @param lenght of challenge response
362  */
363 void goep_client_header_add_challenge_response(uint16_t goep_cid, const uint8_t * data, uint16_t length);
364 
365 /**
366  * @brief Add body
367  * @param goep_cid
368  * @param data
369  * @param lenght
370  */
371 void goep_client_body_add_static(uint16_t goep_cid, const uint8_t * data, uint32_t length);
372 
373 /**
374  * @brief Query remaining buffer size
375  * @param goep_cid
376  * @return size
377  */
378 uint16_t goep_client_body_get_outgoing_buffer_len(uint16_t goep_cid);
379 
380 /**
381  * @brief Add body
382  * @param goep_cid
383  * @param data
384  * @param length
385  * @param ret_length
386  */
387 void goep_client_body_fillup_static(uint16_t goep_cid, const uint8_t * data, uint32_t length, uint32_t * ret_length);
388 
389 /**
390  * @brief Execute prepared request
391  * @param goep_cid
392  * @param daa
393  */
394 int goep_client_execute(uint16_t goep_cid);
395 
396 /**
397  * @brief Execute prepared request with final bit
398  * @param goep_cid
399  * @param final
400  */
401 int goep_client_execute_with_final_bit(uint16_t goep_cid, bool final);
402 
403 /**
404  * @brief De-Init GOEP Client
405  */
406 void goep_client_deinit(void);
407 
408 /* API_END */
409 
410 // 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));
411 
412 #if defined __cplusplus
413 }
414 #endif
415 #endif
416 
417