xref: /btstack/src/classic/goep_client.h (revision c1b6583a190ace9247a1f81941d6be4382eb4f1e)
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 SRMP Waiting
274  * @param goep_cid
275  */
276 void goep_client_header_add_srmp_waiting(uint16_t goep_cid);
277 
278 /**
279  * @brief Add header with single byte value (8 bit)
280  * @param goep_cid
281  * @param header_type
282  * @param value
283  */
284 void goep_client_header_add_byte(uint16_t goep_cid, uint8_t header_type, uint8_t value);
285 
286 /**
287  * @brief Add header with word value (32 bit)
288  * @param goep_cid
289  * @param header_type
290  * @param value
291  */
292 void goep_client_header_add_word(uint16_t goep_cid, uint8_t header_type, uint32_t value);
293 
294 /**
295  * @brief Add header with variable size
296  * @param goep_cid
297  * @param header_type
298  * @param header_data
299  * @param header_data_length
300  */
301 void goep_client_header_add_variable(uint16_t goep_cid, uint8_t header_type, const uint8_t * header_data, uint16_t header_data_length);
302 
303 /**
304  * @brief Add name header to current request
305  * @param goep_cid
306  * @param name
307  */
308 void goep_client_header_add_name(uint16_t goep_cid, const char * name);
309 
310 /**
311  * @brief Add name header to current request
312  * @param goep_cid
313  * @param name
314  * @param name_len
315  */
316 void goep_client_header_add_name_prefix(uint16_t goep_cid, const char * name, uint16_t name_len);
317 
318 /**
319  * @brief Add string encoded as unicode to current request
320  * @param goep_cid
321  * @param name
322  * @param name_len
323  */
324 void goep_client_header_add_unicode_prefix(uint16_t goep_cid, uint8_t header_id, const char * name, uint16_t name_len);
325 
326 /**
327  * @brief Add target header to current request
328  * @param goep_cid
329  * @param target
330  * @param length of target
331  */
332 void goep_client_header_add_target(uint16_t goep_cid, const uint8_t * target, uint16_t length);
333 
334 /**
335  * @brief Add type header to current request
336  * @param goep_cid
337  * @param type
338  */
339 void goep_client_header_add_type(uint16_t goep_cid, const char * type);
340 
341 /**
342  * @brief Add count header to current request
343  * @param goep_cid
344  * @param count
345  */
346 void goep_client_header_add_count(uint16_t goep_cid, uint32_t count);
347 
348 /**
349  * @brief Add length header to current request
350  * @param goep_cid
351  * @param length
352  */
353 void goep_client_header_add_length(uint16_t goep_cid, uint32_t length);
354 
355 /**
356  * @brief Add application parameters header to current request
357  * @param goep_cid
358  * @param data
359  * @param lenght of application parameters
360  */
361 void goep_client_header_add_application_parameters(uint16_t goep_cid, const uint8_t * data, uint16_t length);
362 
363 /**
364  * @brief Add application parameters header to current request
365  * @param goep_cid
366  * @param data
367  * @param lenght of challenge response
368  */
369 void goep_client_header_add_challenge_response(uint16_t goep_cid, const uint8_t * data, uint16_t length);
370 
371 /**
372  * @brief Add body
373  * @param goep_cid
374  * @param data
375  * @param lenght
376  */
377 void goep_client_body_add_static(uint16_t goep_cid, const uint8_t * data, uint32_t length);
378 
379 /**
380  * @brief Query remaining buffer size
381  * @param goep_cid
382  * @return size
383  */
384 uint16_t goep_client_body_get_outgoing_buffer_len(uint16_t goep_cid);
385 
386 /**
387  * @brief Add body
388  * @param goep_cid
389  * @param data
390  * @param length
391  * @param ret_length
392  */
393 void goep_client_body_fillup_static(uint16_t goep_cid, const uint8_t * data, uint32_t length, uint32_t * ret_length);
394 
395 /**
396  * @brief Execute prepared request
397  * @param goep_cid
398  * @param daa
399  */
400 int goep_client_execute(uint16_t goep_cid);
401 
402 /**
403  * @brief Execute prepared request with final bit
404  * @param goep_cid
405  * @param final
406  */
407 int goep_client_execute_with_final_bit(uint16_t goep_cid, bool final);
408 
409 /**
410  * @brief De-Init GOEP Client
411  */
412 void goep_client_deinit(void);
413 
414 /* API_END */
415 
416 // 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));
417 
418 #if defined __cplusplus
419 }
420 #endif
421 #endif
422 
423