1 /******************************************************************************
2 *
3 * Copyright (C) 2010-2013 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19
20 /******************************************************************************
21 *
22 * This file contains the LLCP API code
23 *
24 ******************************************************************************/
25
26 #include <string.h>
27 #include "gki.h"
28 #include "nfc_target.h"
29 #include "bt_types.h"
30 #include "llcp_api.h"
31 #include "llcp_int.h"
32 #include "llcp_defs.h"
33
34 #if (LLCP_TEST_INCLUDED == TRUE) /* this is for LLCP testing */
35
36 tLLCP_TEST_PARAMS llcp_test_params =
37 {
38 LLCP_VERSION_VALUE,
39 0, /* not override */
40 };
41
42 /*******************************************************************************
43 **
44 ** Function LLCP_SetTestParams
45 **
46 ** Description Set test parameters for LLCP
47 **
48 **
49 ** Returns void
50 **
51 *******************************************************************************/
LLCP_SetTestParams(UINT8 version,UINT16 wks)52 void LLCP_SetTestParams (UINT8 version, UINT16 wks)
53 {
54 LLCP_TRACE_API2 ("LLCP_SetTestParams () version:0x%02X, wks:0x%04X",
55 version, wks);
56
57 if (version != 0xFF)
58 llcp_test_params.version = version;
59
60 if (wks != 0xFFFF)
61 llcp_test_params.wks = wks;
62 }
63 #endif
64
65 /*******************************************************************************
66 **
67 ** Function LLCP_SetConfig
68 **
69 ** Description Set configuration parameters for LLCP
70 ** - Local Link MIU
71 ** - Option parameter
72 ** - Response Waiting Time Index
73 ** - Local Link Timeout
74 ** - Inactivity Timeout as initiator role
75 ** - Inactivity Timeout as target role
76 ** - Delay SYMM response
77 ** - Data link connection timeout
78 ** - Delay timeout to send first PDU as initiator
79 **
80 ** Returns void
81 **
82 *******************************************************************************/
LLCP_SetConfig(UINT16 link_miu,UINT8 opt,UINT8 wt,UINT16 link_timeout,UINT16 inact_timeout_init,UINT16 inact_timeout_target,UINT16 symm_delay,UINT16 data_link_timeout,UINT16 delay_first_pdu_timeout)83 void LLCP_SetConfig (UINT16 link_miu,
84 UINT8 opt,
85 UINT8 wt,
86 UINT16 link_timeout,
87 UINT16 inact_timeout_init,
88 UINT16 inact_timeout_target,
89 UINT16 symm_delay,
90 UINT16 data_link_timeout,
91 UINT16 delay_first_pdu_timeout)
92 {
93 LLCP_TRACE_API4 ("LLCP_SetConfig () link_miu:%d, opt:0x%02X, wt:%d, link_timeout:%d",
94 link_miu, opt, wt, link_timeout);
95 LLCP_TRACE_API4 (" inact_timeout (init:%d,target:%d), symm_delay:%d, data_link_timeout:%d",
96 inact_timeout_init, inact_timeout_target, symm_delay, data_link_timeout);
97 LLCP_TRACE_API1 (" delay_first_pdu_timeout:%d", delay_first_pdu_timeout);
98
99 if (link_miu < LLCP_DEFAULT_MIU)
100 {
101 LLCP_TRACE_ERROR1 ("LLCP_SetConfig (): link_miu shall not be smaller than LLCP_DEFAULT_MIU (%d)",
102 LLCP_DEFAULT_MIU);
103 link_miu = LLCP_DEFAULT_MIU;
104 }
105 else if (link_miu > LLCP_MAX_MIU)
106 {
107 LLCP_TRACE_ERROR1 ("LLCP_SetConfig (): link_miu shall not be bigger than LLCP_MAX_MIU (%d)",
108 LLCP_MAX_MIU);
109 link_miu = LLCP_MAX_MIU;
110 }
111
112 /* if Link MIU is bigger than GKI buffer */
113 if (link_miu > LLCP_MIU)
114 {
115 LLCP_TRACE_ERROR1 ("LLCP_SetConfig (): link_miu shall not be bigger than LLCP_MIU (%d)",
116 LLCP_MIU);
117 llcp_cb.lcb.local_link_miu = LLCP_MIU;
118 }
119 else
120 llcp_cb.lcb.local_link_miu = link_miu;
121
122 llcp_cb.lcb.local_opt = opt;
123 llcp_cb.lcb.local_wt = wt;
124
125 if (link_timeout < LLCP_LTO_UNIT)
126 {
127 LLCP_TRACE_ERROR1 ("LLCP_SetConfig (): link_timeout shall not be smaller than LLCP_LTO_UNIT (%d ms)",
128 LLCP_LTO_UNIT);
129 llcp_cb.lcb.local_lto = LLCP_DEFAULT_LTO_IN_MS;
130 }
131 else if (link_timeout > LLCP_MAX_LTO_IN_MS)
132 {
133 LLCP_TRACE_ERROR1 ("LLCP_SetConfig (): link_timeout shall not be bigger than LLCP_MAX_LTO_IN_MS (%d ms)",
134 LLCP_MAX_LTO_IN_MS);
135 llcp_cb.lcb.local_lto = LLCP_MAX_LTO_IN_MS;
136 }
137 else
138 llcp_cb.lcb.local_lto = link_timeout;
139
140 llcp_cb.lcb.inact_timeout_init = inact_timeout_init;
141 llcp_cb.lcb.inact_timeout_target = inact_timeout_target;
142 llcp_cb.lcb.symm_delay = symm_delay;
143 llcp_cb.lcb.data_link_timeout = data_link_timeout;
144 llcp_cb.lcb.delay_first_pdu_timeout = delay_first_pdu_timeout;
145 }
146
147 /*******************************************************************************
148 **
149 ** Function LLCP_GetConfig
150 **
151 ** Description Get configuration parameters for LLCP
152 ** - Local Link MIU
153 ** - Option parameter
154 ** - Response Waiting Time Index
155 ** - Local Link Timeout
156 ** - Inactivity Timeout as initiator role
157 ** - Inactivity Timeout as target role
158 ** - Delay SYMM response
159 ** - Data link connection timeout
160 ** - Delay timeout to send first PDU as initiator
161 **
162 ** Returns void
163 **
164 *******************************************************************************/
LLCP_GetConfig(UINT16 * p_link_miu,UINT8 * p_opt,UINT8 * p_wt,UINT16 * p_link_timeout,UINT16 * p_inact_timeout_init,UINT16 * p_inact_timeout_target,UINT16 * p_symm_delay,UINT16 * p_data_link_timeout,UINT16 * p_delay_first_pdu_timeout)165 void LLCP_GetConfig (UINT16 *p_link_miu,
166 UINT8 *p_opt,
167 UINT8 *p_wt,
168 UINT16 *p_link_timeout,
169 UINT16 *p_inact_timeout_init,
170 UINT16 *p_inact_timeout_target,
171 UINT16 *p_symm_delay,
172 UINT16 *p_data_link_timeout,
173 UINT16 *p_delay_first_pdu_timeout)
174 {
175 *p_link_miu = llcp_cb.lcb.local_link_miu;
176 *p_opt = llcp_cb.lcb.local_opt;
177 *p_wt = llcp_cb.lcb.local_wt;
178 *p_link_timeout = llcp_cb.lcb.local_lto;
179 *p_inact_timeout_init = llcp_cb.lcb.inact_timeout_init;
180 *p_inact_timeout_target = llcp_cb.lcb.inact_timeout_target;
181 *p_symm_delay = llcp_cb.lcb.symm_delay;
182 *p_data_link_timeout = llcp_cb.lcb.data_link_timeout;
183 *p_delay_first_pdu_timeout = llcp_cb.lcb.delay_first_pdu_timeout;
184
185 LLCP_TRACE_API4 ("LLCP_GetConfig () link_miu:%d, opt:0x%02X, wt:%d, link_timeout:%d",
186 *p_link_miu, *p_opt, *p_wt, *p_link_timeout);
187 LLCP_TRACE_API4 (" inact_timeout (init:%d, target:%d), symm_delay:%d, data_link_timeout:%d",
188 *p_inact_timeout_init, *p_inact_timeout_target, *p_symm_delay, *p_data_link_timeout);
189 LLCP_TRACE_API1 (" delay_first_pdu_timeout:%d", *p_delay_first_pdu_timeout);
190 }
191
192 /*******************************************************************************
193 **
194 ** Function LLCP_GetDiscoveryConfig
195 **
196 ** Description Returns discovery config for ISO 18092 MAC link activation
197 ** This function is called to get general bytes for NFC_PMID_ATR_REQ_GEN_BYTES
198 ** or NFC_PMID_ATR_RES_GEN_BYTES before starting discovery.
199 **
200 ** wt:Waiting time 0 - 8, only for listen
201 ** p_gen_bytes: pointer to store LLCP magic number and paramters
202 ** p_gen_bytes_len: length of buffer for gen bytes as input
203 ** (NOTE:it must be bigger than LLCP_MIN_GEN_BYTES)
204 ** actual gen bytes size as output
205 **
206 ** Restrictions on the use of ISO 18092
207 ** 1. The DID features shall not be used.
208 ** 2. the NAD features shall not be used.
209 ** 3. Frame waiting time extentions (WTX) shall not be used.
210 **
211 ** Returns None
212 **
213 *******************************************************************************/
LLCP_GetDiscoveryConfig(UINT8 * p_wt,UINT8 * p_gen_bytes,UINT8 * p_gen_bytes_len)214 void LLCP_GetDiscoveryConfig (UINT8 *p_wt,
215 UINT8 *p_gen_bytes,
216 UINT8 *p_gen_bytes_len)
217 {
218 UINT8 *p = p_gen_bytes;
219
220 LLCP_TRACE_API0 ("LLCP_GetDiscoveryConfig ()");
221
222 if (*p_gen_bytes_len < LLCP_MIN_GEN_BYTES)
223 {
224 LLCP_TRACE_ERROR1 ("LLCP_GetDiscoveryConfig (): GenBytes length shall not be smaller than LLCP_MIN_GEN_BYTES (%d)",
225 LLCP_MIN_GEN_BYTES);
226 *p_gen_bytes_len = 0;
227 return;
228 }
229
230 *p_wt = llcp_cb.lcb.local_wt;
231
232 UINT8_TO_BE_STREAM (p, LLCP_MAGIC_NUMBER_BYTE0);
233 UINT8_TO_BE_STREAM (p, LLCP_MAGIC_NUMBER_BYTE1);
234 UINT8_TO_BE_STREAM (p, LLCP_MAGIC_NUMBER_BYTE2);
235
236 #if (LLCP_TEST_INCLUDED == TRUE) /* this is for LLCP testing */
237 UINT8_TO_BE_STREAM (p, LLCP_VERSION_TYPE);
238 UINT8_TO_BE_STREAM (p, LLCP_VERSION_LEN);
239 UINT8_TO_BE_STREAM (p, llcp_test_params.version);
240
241 UINT8_TO_BE_STREAM (p, LLCP_MIUX_TYPE);
242 UINT8_TO_BE_STREAM (p, LLCP_MIUX_LEN);
243 UINT16_TO_BE_STREAM (p, (llcp_cb.lcb.local_link_miu - LLCP_DEFAULT_MIU));
244
245 UINT8_TO_BE_STREAM (p, LLCP_WKS_TYPE);
246 UINT8_TO_BE_STREAM (p, LLCP_WKS_LEN);
247 if (llcp_test_params.wks == 0) /* not override */
248 {
249 UINT16_TO_BE_STREAM (p, llcp_cb.lcb.wks);
250 }
251 else
252 {
253 UINT16_TO_BE_STREAM (p, llcp_test_params.wks);
254 }
255 #else
256 UINT8_TO_BE_STREAM (p, LLCP_VERSION_TYPE);
257 UINT8_TO_BE_STREAM (p, LLCP_VERSION_LEN);
258 UINT8_TO_BE_STREAM (p, LLCP_VERSION_VALUE);
259
260 UINT8_TO_BE_STREAM (p, LLCP_MIUX_TYPE);
261 UINT8_TO_BE_STREAM (p, LLCP_MIUX_LEN);
262 UINT16_TO_BE_STREAM (p, (llcp_cb.lcb.local_link_miu - LLCP_DEFAULT_MIU));
263
264 UINT8_TO_BE_STREAM (p, LLCP_WKS_TYPE);
265 UINT8_TO_BE_STREAM (p, LLCP_WKS_LEN);
266 UINT16_TO_BE_STREAM (p, llcp_cb.lcb.wks);
267 #endif
268
269 UINT8_TO_BE_STREAM (p, LLCP_LTO_TYPE);
270 UINT8_TO_BE_STREAM (p, LLCP_LTO_LEN);
271 UINT8_TO_BE_STREAM (p, (llcp_cb.lcb.local_lto/LLCP_LTO_UNIT));
272
273 UINT8_TO_BE_STREAM (p, LLCP_OPT_TYPE);
274 UINT8_TO_BE_STREAM (p, LLCP_OPT_LEN);
275 UINT8_TO_BE_STREAM (p, llcp_cb.lcb.local_opt);
276
277 *p_gen_bytes_len = (UINT8) (p - p_gen_bytes);
278 }
279
280 /*******************************************************************************
281 **
282 ** Function LLCP_ActivateLink
283 **
284 ** Description This function will activate LLCP link with LR, WT and Gen Bytes
285 ** in activation NTF from NFCC.
286 **
287 ** LLCP_LINK_ACTIVATION_COMPLETE_EVT will be returned through
288 ** callback function if successful.
289 ** Otherwise, LLCP_LINK_ACTIVATION_FAILED_EVT will be returned.
290 **
291 ** Returns LLCP_STATUS_SUCCESS if success
292 **
293 *******************************************************************************/
LLCP_ActivateLink(tLLCP_ACTIVATE_CONFIG config,tLLCP_LINK_CBACK * p_link_cback)294 tLLCP_STATUS LLCP_ActivateLink (tLLCP_ACTIVATE_CONFIG config,
295 tLLCP_LINK_CBACK *p_link_cback)
296 {
297 LLCP_TRACE_API1 ("LLCP_ActivateLink () link_state = %d", llcp_cb.lcb.link_state);
298
299 if ( (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATED)
300 &&(p_link_cback) )
301 {
302 llcp_cb.lcb.p_link_cback = p_link_cback;
303 return (llcp_link_activate (&config));
304 }
305 else
306 return LLCP_STATUS_FAIL;
307 }
308
309 /*******************************************************************************
310 **
311 ** Function LLCP_DeactivateLink
312 **
313 ** Description Deactivate LLCP link
314 **
315 ** LLCP_LINK_DEACTIVATED_EVT will be returned through callback
316 ** when LLCP link is deactivated. Then NFC link may be deactivated.
317 **
318 ** Returns LLCP_STATUS_SUCCESS if success
319 **
320 *******************************************************************************/
LLCP_DeactivateLink(void)321 tLLCP_STATUS LLCP_DeactivateLink (void)
322 {
323 LLCP_TRACE_API1 ("LLCP_DeactivateLink () link_state = %d", llcp_cb.lcb.link_state);
324
325 if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_DEACTIVATED)
326 {
327 llcp_link_deactivate (LLCP_LINK_LOCAL_INITIATED);
328 return LLCP_STATUS_SUCCESS;
329 }
330 else
331 return LLCP_STATUS_FAIL;
332 }
333
334 /*******************************************************************************
335 **
336 ** Function LLCP_RegisterServer
337 **
338 ** Description Register server and callback function
339 **
340 ** reg_sap : Well-Known SAP except LM and SDP (0x02 - 0x0F)
341 ** Advertized by SDP (0x10 - 0x1F)
342 ** LLCP_INVALID_SAP, LLCP will allocate between 0x10 and 0x1F
343 ** link_type : LLCP_LINK_TYPE_LOGICAL_DATA_LINK
344 ** and/or LLCP_LINK_TYPE_DATA_LINK_CONNECTION
345 ** p_service_name : Null-terminated string up to LLCP_MAX_SN_LEN
346 **
347 ** Returns SAP between 0x02 and 0x1F, if success
348 ** LLCP_INVALID_SAP, otherwise
349 **
350 *******************************************************************************/
LLCP_RegisterServer(UINT8 reg_sap,UINT8 link_type,char * p_service_name,tLLCP_APP_CBACK * p_app_cback)351 UINT8 LLCP_RegisterServer (UINT8 reg_sap,
352 UINT8 link_type,
353 char *p_service_name,
354 tLLCP_APP_CBACK *p_app_cback)
355 {
356 UINT8 sap;
357 UINT16 length;
358 tLLCP_APP_CB *p_app_cb;
359
360 LLCP_TRACE_API3 ("LLCP_RegisterServer (): SAP:0x%x, link_type:0x%x, ServiceName:<%s>",
361 reg_sap, link_type, ((p_service_name == NULL) ? "" : p_service_name));
362
363 if (!p_app_cback)
364 {
365 LLCP_TRACE_ERROR0 ("LLCP_RegisterServer (): Callback must be provided");
366 return LLCP_INVALID_SAP;
367 }
368 else if ( ((link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0x00)
369 &&((link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0x00) )
370 {
371 LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): link type (0x%x) must be specified", link_type);
372 return LLCP_INVALID_SAP;
373 }
374
375 if (reg_sap == LLCP_INVALID_SAP)
376 {
377 /* allocate a SAP between 0x10 and 0x1F */
378 for (sap = 0; sap < LLCP_MAX_SERVER; sap++)
379 {
380 if (llcp_cb.server_cb[sap].p_app_cback == NULL)
381 {
382 p_app_cb = &llcp_cb.server_cb[sap];
383 reg_sap = LLCP_LOWER_BOUND_SDP_SAP + sap;
384 break;
385 }
386 }
387
388 if (reg_sap == LLCP_INVALID_SAP)
389 {
390 LLCP_TRACE_ERROR0 ("LLCP_RegisterServer (): out of resource");
391 return LLCP_INVALID_SAP;
392 }
393 }
394 else if (reg_sap == LLCP_SAP_LM)
395 {
396 LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): SAP (0x%x) is for link manager", reg_sap);
397 return LLCP_INVALID_SAP;
398 }
399 else if (reg_sap <= LLCP_UPPER_BOUND_WK_SAP)
400 {
401 if (reg_sap >= LLCP_MAX_WKS)
402 {
403 LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): out of resource for SAP (0x%x)", reg_sap);
404 return LLCP_INVALID_SAP;
405 }
406 else if (llcp_cb.wks_cb[reg_sap].p_app_cback)
407 {
408 LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): SAP (0x%x) is already registered", reg_sap);
409 return LLCP_INVALID_SAP;
410 }
411 else
412 {
413 p_app_cb = &llcp_cb.wks_cb[reg_sap];
414 }
415 }
416 else if (reg_sap <= LLCP_UPPER_BOUND_SDP_SAP)
417 {
418 if (reg_sap - LLCP_LOWER_BOUND_SDP_SAP >= LLCP_MAX_SERVER)
419 {
420 LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): out of resource for SAP (0x%x)", reg_sap);
421 return LLCP_INVALID_SAP;
422 }
423 else if (llcp_cb.server_cb[reg_sap - LLCP_LOWER_BOUND_SDP_SAP].p_app_cback)
424 {
425 LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): SAP (0x%x) is already registered", reg_sap);
426 return LLCP_INVALID_SAP;
427 }
428 else
429 {
430 p_app_cb = &llcp_cb.server_cb[reg_sap - LLCP_LOWER_BOUND_SDP_SAP];
431 }
432 }
433 else if (reg_sap >= LLCP_LOWER_BOUND_LOCAL_SAP)
434 {
435 LLCP_TRACE_ERROR2 ("LLCP_RegisterServer (): SAP (0x%x) must be less than 0x%x",
436 reg_sap, LLCP_LOWER_BOUND_LOCAL_SAP);
437 return LLCP_INVALID_SAP;
438 }
439
440 memset (p_app_cb, 0x00, sizeof (tLLCP_APP_CB));
441
442 if (p_service_name)
443 {
444 length = (UINT8) strlen (p_service_name);
445 if (length > LLCP_MAX_SN_LEN)
446 {
447 LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): Service Name (%d bytes) is too long", length);
448 return LLCP_INVALID_SAP;
449 }
450
451 p_app_cb->p_service_name = (UINT8 *) GKI_getbuf ((UINT16) (length + 1));
452 if (p_app_cb->p_service_name == NULL)
453 {
454 LLCP_TRACE_ERROR0 ("LLCP_RegisterServer (): Out of resource");
455 return LLCP_INVALID_SAP;
456 }
457
458 BCM_STRNCPY_S ((char *) p_app_cb->p_service_name, length + 1, (char *) p_service_name, length + 1);
459 p_app_cb->p_service_name[length] = 0;
460 }
461 else
462 p_app_cb->p_service_name = NULL;
463
464 p_app_cb->p_app_cback = p_app_cback;
465 p_app_cb->link_type = link_type;
466
467 if (reg_sap <= LLCP_UPPER_BOUND_WK_SAP)
468 {
469 llcp_cb.lcb.wks |= (1 << reg_sap);
470 }
471
472 LLCP_TRACE_DEBUG1 ("LLCP_RegisterServer (): Registered SAP = 0x%02X", reg_sap);
473
474 if (link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)
475 {
476 llcp_cb.num_logical_data_link++;
477 llcp_util_adjust_ll_congestion ();
478 }
479
480 return reg_sap;
481 }
482
483 /*******************************************************************************
484 **
485 ** Function LLCP_RegisterClient
486 **
487 ** Description Register client and callback function
488 **
489 ** link_type : LLCP_LINK_TYPE_LOGICAL_DATA_LINK
490 ** and/or LLCP_LINK_TYPE_DATA_LINK_CONNECTION
491 **
492 ** Returns SAP between 0x20 and 0x3F, if success
493 ** LLCP_INVALID_SAP, otherwise
494 **
495 *******************************************************************************/
LLCP_RegisterClient(UINT8 link_type,tLLCP_APP_CBACK * p_app_cback)496 UINT8 LLCP_RegisterClient (UINT8 link_type,
497 tLLCP_APP_CBACK *p_app_cback)
498 {
499 UINT8 reg_sap = LLCP_INVALID_SAP;
500 UINT8 sap;
501 tLLCP_APP_CB *p_app_cb;
502
503 LLCP_TRACE_API1 ("LLCP_RegisterClient (): link_type = 0x%x", link_type);
504
505 if (!p_app_cback)
506 {
507 LLCP_TRACE_ERROR0 ("LLCP_RegisterClient (): Callback must be provided");
508 return LLCP_INVALID_SAP;
509 }
510 else if ( ((link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0x00)
511 &&((link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0x00) )
512 {
513 LLCP_TRACE_ERROR1 ("LLCP_RegisterClient (): link type (0x%x) must be specified", link_type);
514 return LLCP_INVALID_SAP;
515 }
516
517 /* allocate a SAP between 0x20 and 0x3F */
518 for (sap = 0; sap < LLCP_MAX_CLIENT; sap++)
519 {
520 if (llcp_cb.client_cb[sap].p_app_cback == NULL)
521 {
522 p_app_cb = &llcp_cb.client_cb[sap];
523 memset (p_app_cb, 0x00, sizeof (tLLCP_APP_CB));
524 reg_sap = LLCP_LOWER_BOUND_LOCAL_SAP + sap;
525 break;
526 }
527 }
528
529 if (reg_sap == LLCP_INVALID_SAP)
530 {
531 LLCP_TRACE_ERROR0 ("LLCP_RegisterClient (): out of resource");
532 return LLCP_INVALID_SAP;
533 }
534
535 p_app_cb->p_app_cback = p_app_cback;
536 p_app_cb->p_service_name = NULL;
537 p_app_cb->link_type = link_type;
538
539 LLCP_TRACE_DEBUG1 ("LLCP_RegisterClient (): Registered SAP = 0x%02X", reg_sap);
540
541 if (link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)
542 {
543 llcp_cb.num_logical_data_link++;
544 llcp_util_adjust_ll_congestion ();
545 }
546
547 return reg_sap;
548 }
549
550 /*******************************************************************************
551 **
552 ** Function LLCP_Deregister
553 **
554 ** Description Deregister server or client
555 **
556 **
557 ** Returns LLCP_STATUS_SUCCESS if success
558 **
559 *******************************************************************************/
LLCP_Deregister(UINT8 local_sap)560 tLLCP_STATUS LLCP_Deregister (UINT8 local_sap)
561 {
562 UINT8 idx;
563 tLLCP_APP_CB *p_app_cb;
564
565 LLCP_TRACE_API1 ("LLCP_Deregister () SAP:0x%x", local_sap);
566
567 p_app_cb = llcp_util_get_app_cb (local_sap);
568
569 if ((!p_app_cb) || (p_app_cb->p_app_cback == NULL))
570 {
571 LLCP_TRACE_ERROR1 ("LLCP_Deregister (): SAP (0x%x) is not registered", local_sap);
572 return LLCP_STATUS_FAIL;
573 }
574
575 if (p_app_cb->p_service_name)
576 GKI_freebuf (p_app_cb->p_service_name);
577
578 /* update WKS bit map */
579 if (local_sap <= LLCP_UPPER_BOUND_WK_SAP)
580 {
581 llcp_cb.lcb.wks &= ~ (1 << local_sap);
582 }
583
584 /* discard any received UI PDU on this SAP */
585 LLCP_FlushLogicalLinkRxData (local_sap);
586 llcp_cb.total_rx_ui_pdu = 0;
587
588 /* deallocate any data link connection on this SAP */
589 for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++)
590 {
591 if ( (llcp_cb.dlcb[idx].state != LLCP_DLC_STATE_IDLE)
592 &&(llcp_cb.dlcb[idx].local_sap == local_sap) )
593 {
594 llcp_util_deallocate_data_link (&llcp_cb.dlcb[idx]);
595 }
596 }
597
598 p_app_cb->p_app_cback = NULL;
599
600 /* discard any pending tx UI PDU from this SAP */
601 while (p_app_cb->ui_xmit_q.p_first)
602 {
603 GKI_freebuf (GKI_dequeue (&p_app_cb->ui_xmit_q));
604 llcp_cb.total_tx_ui_pdu--;
605 }
606
607 if (p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)
608 {
609 llcp_cb.num_logical_data_link--;
610 llcp_util_adjust_ll_congestion ();
611 }
612
613 /* check rx congestion status */
614 llcp_util_check_rx_congested_status ();
615
616 return LLCP_STATUS_SUCCESS;
617 }
618
619 /*******************************************************************************
620 **
621 ** Function LLCP_IsLogicalLinkCongested
622 **
623 ** Description Check if logical link is congested
624 **
625 **
626 ** Returns TRUE if congested
627 **
628 *******************************************************************************/
LLCP_IsLogicalLinkCongested(UINT8 local_sap,UINT8 num_pending_ui_pdu,UINT8 total_pending_ui_pdu,UINT8 total_pending_i_pdu)629 BOOLEAN LLCP_IsLogicalLinkCongested (UINT8 local_sap,
630 UINT8 num_pending_ui_pdu,
631 UINT8 total_pending_ui_pdu,
632 UINT8 total_pending_i_pdu)
633 {
634 tLLCP_APP_CB *p_app_cb;
635
636 LLCP_TRACE_API4 ("LLCP_IsLogicalLinkCongested () Local SAP:0x%x, pending = (%d, %d, %d)",
637 local_sap, num_pending_ui_pdu, total_pending_ui_pdu, total_pending_i_pdu);
638
639 p_app_cb = llcp_util_get_app_cb (local_sap);
640
641 if ( (llcp_cb.lcb.link_state != LLCP_LINK_STATE_ACTIVATED)
642 ||(p_app_cb == NULL)
643 ||(p_app_cb->p_app_cback == NULL)
644 ||((p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0)
645 ||(p_app_cb->is_ui_tx_congested) )
646 {
647 return (TRUE);
648 }
649 else if ( (num_pending_ui_pdu + p_app_cb->ui_xmit_q.count >= llcp_cb.ll_tx_congest_start)
650 ||(total_pending_ui_pdu + llcp_cb.total_tx_ui_pdu >= llcp_cb.max_num_ll_tx_buff)
651 ||(total_pending_ui_pdu + total_pending_i_pdu + llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu >= llcp_cb.max_num_tx_buff) )
652 {
653 /* set flag so LLCP can notify uncongested status later */
654 p_app_cb->is_ui_tx_congested = TRUE;
655
656 return (TRUE);
657 }
658 return (FALSE);
659 }
660
661 /*******************************************************************************
662 **
663 ** Function LLCP_SendUI
664 **
665 ** Description Send connnectionless data to DSAP
666 **
667 **
668 ** Returns LLCP_STATUS_SUCCESS if success
669 ** LLCP_STATUS_CONGESTED if logical link is congested
670 ** LLCP_STATUS_FAIL, otherwise
671 **
672 *******************************************************************************/
LLCP_SendUI(UINT8 ssap,UINT8 dsap,BT_HDR * p_buf)673 tLLCP_STATUS LLCP_SendUI (UINT8 ssap,
674 UINT8 dsap,
675 BT_HDR *p_buf)
676 {
677 tLLCP_STATUS status = LLCP_STATUS_FAIL;
678 tLLCP_APP_CB *p_app_cb;
679
680 LLCP_TRACE_API2 ("LLCP_SendUI () SSAP=0x%x, DSAP=0x%x", ssap, dsap);
681
682 p_app_cb = llcp_util_get_app_cb (ssap);
683
684 if ( (p_app_cb == NULL)
685 ||(p_app_cb->p_app_cback == NULL) )
686 {
687 LLCP_TRACE_ERROR1 ("LLCP_SendUI (): SSAP (0x%x) is not registered", ssap);
688 }
689 else if ((p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0)
690 {
691 LLCP_TRACE_ERROR1 ("LLCP_SendUI (): Logical link on SSAP (0x%x) is not enabled", ssap);
692 }
693 else if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_ACTIVATED)
694 {
695 LLCP_TRACE_ERROR0 ("LLCP_SendUI (): LLCP link is not activated");
696 }
697 else if ( (llcp_cb.lcb.peer_opt == LLCP_LSC_UNKNOWN)
698 ||(llcp_cb.lcb.peer_opt & LLCP_LSC_1) )
699 {
700 if (p_buf->len <= llcp_cb.lcb.peer_miu)
701 {
702 if (p_buf->offset >= LLCP_MIN_OFFSET)
703 {
704 status = llcp_util_send_ui (ssap, dsap, p_app_cb, p_buf);
705 }
706 else
707 {
708 LLCP_TRACE_ERROR2 ("LLCP_SendUI (): offset (%d) must be %d at least",
709 p_buf->offset, LLCP_MIN_OFFSET );
710 }
711 }
712 else
713 {
714 LLCP_TRACE_ERROR0 ("LLCP_SendUI (): Data length shall not be bigger than peer's link MIU");
715 }
716 }
717 else
718 {
719 LLCP_TRACE_ERROR0 ("LLCP_SendUI (): Peer doesn't support connectionless link");
720 }
721
722 if (status == LLCP_STATUS_FAIL)
723 {
724 GKI_freebuf (p_buf);
725 }
726
727 return status;
728 }
729
730 /*******************************************************************************
731 **
732 ** Function LLCP_ReadLogicalLinkData
733 **
734 ** Description Read information of UI PDU for local SAP
735 **
736 ** - Remote SAP who sent UI PDU is returned.
737 ** - Information of UI PDU up to max_data_len is copied into p_data.
738 ** - Information of next UI PDU is not concatenated.
739 ** - Recommended max_data_len is link MIU of local device
740 **
741 ** Returns TRUE if more information of UI PDU or more UI PDU in queue
742 **
743 *******************************************************************************/
LLCP_ReadLogicalLinkData(UINT8 local_sap,UINT32 max_data_len,UINT8 * p_remote_sap,UINT32 * p_data_len,UINT8 * p_data)744 BOOLEAN LLCP_ReadLogicalLinkData (UINT8 local_sap,
745 UINT32 max_data_len,
746 UINT8 *p_remote_sap,
747 UINT32 *p_data_len,
748 UINT8 *p_data)
749 {
750 tLLCP_APP_CB *p_app_cb;
751 BT_HDR *p_buf;
752 UINT8 *p_ui_pdu;
753 UINT16 pdu_hdr, ui_pdu_length;
754
755 LLCP_TRACE_API1 ("LLCP_ReadLogicalLinkData () Local SAP:0x%x", local_sap);
756
757 *p_data_len = 0;
758
759 p_app_cb = llcp_util_get_app_cb (local_sap);
760
761 /* if application is registered */
762 if ((p_app_cb) && (p_app_cb->p_app_cback))
763 {
764 /* if any UI PDU in rx queue */
765 if (p_app_cb->ui_rx_q.p_first)
766 {
767 p_buf = (BT_HDR *) p_app_cb->ui_rx_q.p_first;
768 p_ui_pdu = (UINT8*) (p_buf + 1) + p_buf->offset;
769
770 /* get length of UI PDU */
771 BE_STREAM_TO_UINT16 (ui_pdu_length, p_ui_pdu);
772
773 /* get remote SAP from LLCP header */
774 BE_STREAM_TO_UINT16 (pdu_hdr, p_ui_pdu);
775 *p_remote_sap = LLCP_GET_SSAP (pdu_hdr);
776
777 /* layer_specific has the offset to read within UI PDU */
778 p_ui_pdu += p_buf->layer_specific;
779
780 /* copy data up to max_data_len */
781 if (max_data_len >= (UINT32) (ui_pdu_length - LLCP_PDU_HEADER_SIZE - p_buf->layer_specific))
782 {
783 /* copy information without LLCP header */
784 *p_data_len = (UINT32) (ui_pdu_length - LLCP_PDU_HEADER_SIZE - p_buf->layer_specific);
785
786 /* move to next UI PDU if any */
787 p_buf->layer_specific = 0; /* reset offset to read from the first byte of next UI PDU */
788 p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
789 p_buf->len -= LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
790 }
791 else
792 {
793 *p_data_len = max_data_len;
794
795 /* update offset to read from remaining UI PDU next time */
796 p_buf->layer_specific += max_data_len;
797 }
798
799 memcpy (p_data, p_ui_pdu, *p_data_len);
800
801 /* if read all of UI PDU */
802 if (p_buf->len == 0)
803 {
804 GKI_dequeue (&p_app_cb->ui_rx_q);
805 GKI_freebuf (p_buf);
806
807 /* decrease number of received UI PDU in in all of ui_rx_q and check rx congestion status */
808 llcp_cb.total_rx_ui_pdu--;
809 llcp_util_check_rx_congested_status ();
810 }
811 }
812
813 /* if there is more UI PDU in rx queue */
814 if (p_app_cb->ui_rx_q.p_first)
815 {
816 return (TRUE);
817 }
818 else
819 {
820 return (FALSE);
821 }
822 }
823 else
824 {
825 LLCP_TRACE_ERROR1 ("LLCP_ReadLogicalLinkData (): Unregistered SAP:0x%x", local_sap);
826
827 return (FALSE);
828 }
829 }
830
831 /*******************************************************************************
832 **
833 ** Function LLCP_FlushLogicalLinkRxData
834 **
835 ** Description Discard received data in logical data link of local SAP
836 **
837 **
838 ** Returns length of data flushed
839 **
840 *******************************************************************************/
LLCP_FlushLogicalLinkRxData(UINT8 local_sap)841 UINT32 LLCP_FlushLogicalLinkRxData (UINT8 local_sap)
842 {
843 BT_HDR *p_buf;
844 UINT32 flushed_length = 0;
845 tLLCP_APP_CB *p_app_cb;
846 UINT8 *p_ui_pdu;
847 UINT16 ui_pdu_length;
848
849 LLCP_TRACE_API1 ("LLCP_FlushLogicalLinkRxData () Local SAP:0x%x", local_sap);
850
851 p_app_cb = llcp_util_get_app_cb (local_sap);
852
853 /* if application is registered */
854 if ((p_app_cb) && (p_app_cb->p_app_cback))
855 {
856 /* if any UI PDU in rx queue */
857 while (p_app_cb->ui_rx_q.p_first)
858 {
859 p_buf = (BT_HDR *) p_app_cb->ui_rx_q.p_first;
860 p_ui_pdu = (UINT8*) (p_buf + 1) + p_buf->offset;
861
862 /* get length of UI PDU */
863 BE_STREAM_TO_UINT16 (ui_pdu_length, p_ui_pdu);
864
865 flushed_length += (UINT32) (ui_pdu_length - LLCP_PDU_HEADER_SIZE - p_buf->layer_specific);
866
867 /* move to next UI PDU if any */
868 p_buf->layer_specific = 0; /* offset */
869 p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
870 p_buf->len -= LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
871
872 /* if read all of UI PDU */
873 if (p_buf->len == 0)
874 {
875 GKI_dequeue (&p_app_cb->ui_rx_q);
876 GKI_freebuf (p_buf);
877 llcp_cb.total_rx_ui_pdu--;
878 }
879 }
880
881 /* number of received UI PDU is decreased so check rx congestion status */
882 llcp_util_check_rx_congested_status ();
883 }
884 else
885 {
886 LLCP_TRACE_ERROR1 ("LLCP_FlushLogicalLinkRxData (): Unregistered SAP:0x%x", local_sap);
887 }
888
889 return (flushed_length);
890 }
891
892 /*******************************************************************************
893 **
894 ** Function LLCP_ConnectReq
895 **
896 ** Description Create data link connection between registered SAP and DSAP
897 ** in peer LLCP,
898 **
899 **
900 ** Returns LLCP_STATUS_SUCCESS if success
901 ** LLCP_STATUS_FAIL, otherwise
902 **
903 *******************************************************************************/
LLCP_ConnectReq(UINT8 reg_sap,UINT8 dsap,tLLCP_CONNECTION_PARAMS * p_params)904 tLLCP_STATUS LLCP_ConnectReq (UINT8 reg_sap,
905 UINT8 dsap,
906 tLLCP_CONNECTION_PARAMS *p_params)
907 {
908 tLLCP_DLCB *p_dlcb;
909 tLLCP_STATUS status;
910 tLLCP_APP_CB *p_app_cb;
911
912 LLCP_TRACE_API2 ("LLCP_ConnectReq () reg_sap=0x%x, DSAP=0x%x", reg_sap, dsap);
913
914 if ( (llcp_cb.lcb.peer_opt != LLCP_LSC_UNKNOWN)
915 &&((llcp_cb.lcb.peer_opt & LLCP_LSC_2) == 0) )
916 {
917 LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): Peer doesn't support connection-oriented link");
918 return LLCP_STATUS_FAIL;
919 }
920
921 p_app_cb = llcp_util_get_app_cb (reg_sap);
922
923 /* if application is registered */
924 if ( (p_app_cb == NULL)
925 ||(p_app_cb->p_app_cback == NULL) )
926 {
927 LLCP_TRACE_ERROR1 ("LLCP_ConnectReq (): SSAP (0x%x) is not registered", reg_sap);
928 return LLCP_STATUS_FAIL;
929 }
930
931 if (dsap == LLCP_SAP_LM)
932 {
933 LLCP_TRACE_ERROR1 ("LLCP_ConnectReq (): DSAP (0x%x) must not be link manager SAP", dsap);
934 return LLCP_STATUS_FAIL;
935 }
936
937 if (dsap == LLCP_SAP_SDP)
938 {
939 if (strlen (p_params->sn) > LLCP_MAX_SN_LEN)
940 {
941 LLCP_TRACE_ERROR1 ("LLCP_ConnectReq (): Service Name (%d bytes) is too long",
942 strlen (p_params->sn));
943 return LLCP_STATUS_FAIL;
944 }
945 }
946
947 if ((p_params) && (p_params->miu > llcp_cb.lcb.local_link_miu))
948 {
949 LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): Data link MIU shall not be bigger than local link MIU");
950 return LLCP_STATUS_FAIL;
951 }
952
953 /* check if any pending connection request on this reg_sap */
954 p_dlcb = llcp_dlc_find_dlcb_by_sap (reg_sap, LLCP_INVALID_SAP);
955 if (p_dlcb)
956 {
957 /*
958 ** Accepting LLCP may change SAP in CC, so we cannot find right data link connection
959 ** if there is multiple pending connection request on the same local SAP.
960 */
961 LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): There is pending connect request on this reg_sap");
962 return LLCP_STATUS_FAIL;
963 }
964
965 p_dlcb = llcp_util_allocate_data_link (reg_sap, dsap);
966
967 if (p_dlcb)
968 {
969 status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_CONNECT_REQ, p_params);
970 if (status != LLCP_STATUS_SUCCESS)
971 {
972 LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): Error in state machine");
973 llcp_util_deallocate_data_link (p_dlcb);
974 return LLCP_STATUS_FAIL;
975 }
976 }
977 else
978 {
979 return LLCP_STATUS_FAIL;
980 }
981
982 return LLCP_STATUS_SUCCESS;
983 }
984
985 /*******************************************************************************
986 **
987 ** Function LLCP_ConnectCfm
988 **
989 ** Description Accept connection request from peer LLCP
990 **
991 **
992 ** Returns LLCP_STATUS_SUCCESS if success
993 ** LLCP_STATUS_FAIL, otherwise
994 **
995 *******************************************************************************/
LLCP_ConnectCfm(UINT8 local_sap,UINT8 remote_sap,tLLCP_CONNECTION_PARAMS * p_params)996 tLLCP_STATUS LLCP_ConnectCfm (UINT8 local_sap,
997 UINT8 remote_sap,
998 tLLCP_CONNECTION_PARAMS *p_params)
999 {
1000 tLLCP_STATUS status;
1001 tLLCP_DLCB *p_dlcb;
1002
1003 LLCP_TRACE_API2 ("LLCP_ConnectCfm () Local SAP:0x%x, Remote SAP:0x%x)",
1004 local_sap, remote_sap);
1005
1006 if (!p_params)
1007 {
1008 LLCP_TRACE_ERROR0 ("LLCP_ConnectCfm (): tLLCP_CONNECTION_PARAMS must be provided");
1009 return LLCP_STATUS_FAIL;
1010 }
1011 else if (p_params->miu > llcp_cb.lcb.local_link_miu)
1012 {
1013 LLCP_TRACE_ERROR0 ("LLCP_ConnectCfm (): Data link MIU shall not be bigger than local link MIU");
1014 return LLCP_STATUS_FAIL;
1015 }
1016
1017 p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1018
1019 if (p_dlcb)
1020 {
1021 status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_CONNECT_CFM, p_params);
1022 }
1023 else
1024 {
1025 LLCP_TRACE_ERROR0 ("LLCP_ConnectCfm (): No data link");
1026 status = LLCP_STATUS_FAIL;
1027 }
1028
1029 return status;
1030 }
1031
1032 /*******************************************************************************
1033 **
1034 ** Function LLCP_ConnectReject
1035 **
1036 ** Description Reject connection request from peer LLCP
1037 **
1038 ** reason : LLCP_SAP_DM_REASON_APP_REJECTED
1039 ** LLCP_SAP_DM_REASON_PERM_REJECT_THIS
1040 ** LLCP_SAP_DM_REASON_PERM_REJECT_ANY
1041 ** LLCP_SAP_DM_REASON_TEMP_REJECT_THIS
1042 ** LLCP_SAP_DM_REASON_TEMP_REJECT_ANY
1043 **
1044 ** Returns LLCP_STATUS_SUCCESS if success
1045 ** LLCP_STATUS_FAIL, otherwise
1046 **
1047 *******************************************************************************/
LLCP_ConnectReject(UINT8 local_sap,UINT8 remote_sap,UINT8 reason)1048 tLLCP_STATUS LLCP_ConnectReject (UINT8 local_sap,
1049 UINT8 remote_sap,
1050 UINT8 reason)
1051 {
1052 tLLCP_STATUS status;
1053 tLLCP_DLCB *p_dlcb;
1054
1055 LLCP_TRACE_API3 ("LLCP_ConnectReject () Local SAP:0x%x, Remote SAP:0x%x, reason:0x%x",
1056 local_sap, remote_sap, reason);
1057
1058 p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1059
1060 if (p_dlcb)
1061 {
1062 status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_CONNECT_REJECT, &reason);
1063 llcp_util_deallocate_data_link (p_dlcb);
1064 }
1065 else
1066 {
1067 LLCP_TRACE_ERROR0 ("LLCP_ConnectReject (): No data link");
1068 status = LLCP_STATUS_FAIL;
1069 }
1070
1071 return status;
1072 }
1073
1074 /*******************************************************************************
1075 **
1076 ** Function LLCP_IsDataLinkCongested
1077 **
1078 ** Description Check if data link connection is congested
1079 **
1080 **
1081 ** Returns TRUE if congested
1082 **
1083 *******************************************************************************/
LLCP_IsDataLinkCongested(UINT8 local_sap,UINT8 remote_sap,UINT8 num_pending_i_pdu,UINT8 total_pending_ui_pdu,UINT8 total_pending_i_pdu)1084 BOOLEAN LLCP_IsDataLinkCongested (UINT8 local_sap,
1085 UINT8 remote_sap,
1086 UINT8 num_pending_i_pdu,
1087 UINT8 total_pending_ui_pdu,
1088 UINT8 total_pending_i_pdu)
1089 {
1090 tLLCP_DLCB *p_dlcb;
1091
1092 LLCP_TRACE_API5 ("LLCP_IsDataLinkCongested () Local SAP:0x%x, Remote SAP:0x%x, pending = (%d, %d, %d)",
1093 local_sap, remote_sap, num_pending_i_pdu, total_pending_ui_pdu, total_pending_i_pdu);
1094
1095 p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1096
1097 if (p_dlcb)
1098 {
1099 if ( (p_dlcb->is_tx_congested)
1100 ||(p_dlcb->remote_busy) )
1101 {
1102 return (TRUE);
1103 }
1104 else if ( (num_pending_i_pdu + p_dlcb->i_xmit_q.count >= p_dlcb->remote_rw)
1105 ||(total_pending_ui_pdu + total_pending_i_pdu + llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu >= llcp_cb.max_num_tx_buff) )
1106 {
1107 /* set flag so LLCP can notify uncongested status later */
1108 p_dlcb->is_tx_congested = TRUE;
1109 return (TRUE);
1110 }
1111 return (FALSE);
1112 }
1113 return (TRUE);
1114 }
1115
1116 /*******************************************************************************
1117 **
1118 ** Function LLCP_SendData
1119 **
1120 ** Description Send connection-oriented data
1121 **
1122 **
1123 ** Returns LLCP_STATUS_SUCCESS if success
1124 ** LLCP_STATUS_CONGESTED if data link is congested
1125 **
1126 *******************************************************************************/
LLCP_SendData(UINT8 local_sap,UINT8 remote_sap,BT_HDR * p_buf)1127 tLLCP_STATUS LLCP_SendData (UINT8 local_sap,
1128 UINT8 remote_sap,
1129 BT_HDR *p_buf)
1130 {
1131 tLLCP_STATUS status = LLCP_STATUS_FAIL;
1132 tLLCP_DLCB *p_dlcb;
1133
1134 LLCP_TRACE_API2 ("LLCP_SendData () Local SAP:0x%x, Remote SAP:0x%x",
1135 local_sap, remote_sap);
1136
1137 p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1138
1139 if (p_dlcb)
1140 {
1141 if (p_dlcb->remote_miu >= p_buf->len)
1142 {
1143 if (p_buf->offset >= LLCP_MIN_OFFSET)
1144 {
1145 status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DATA_REQ, p_buf);
1146 }
1147 else
1148 {
1149 LLCP_TRACE_ERROR2 ("LLCP_SendData (): offset (%d) must be %d at least",
1150 p_buf->offset, LLCP_MIN_OFFSET );
1151 }
1152 }
1153 else
1154 {
1155 LLCP_TRACE_ERROR2 ("LLCP_SendData (): Information (%d bytes) cannot be more than peer MIU (%d bytes)",
1156 p_buf->len, p_dlcb->remote_miu);
1157 }
1158 }
1159 else
1160 {
1161 LLCP_TRACE_ERROR0 ("LLCP_SendData (): No data link");
1162 }
1163
1164 if (status == LLCP_STATUS_FAIL)
1165 {
1166 GKI_freebuf (p_buf);
1167 }
1168
1169 return status;
1170 }
1171
1172 /*******************************************************************************
1173 **
1174 ** Function LLCP_ReadDataLinkData
1175 **
1176 ** Description Read information of I PDU for data link connection
1177 **
1178 ** - Information of I PDU up to max_data_len is copied into p_data.
1179 ** - Information of next I PDU is not concatenated.
1180 ** - Recommended max_data_len is data link connection MIU of local
1181 ** end point
1182 **
1183 ** Returns TRUE if more data in queue
1184 **
1185 *******************************************************************************/
LLCP_ReadDataLinkData(UINT8 local_sap,UINT8 remote_sap,UINT32 max_data_len,UINT32 * p_data_len,UINT8 * p_data)1186 BOOLEAN LLCP_ReadDataLinkData (UINT8 local_sap,
1187 UINT8 remote_sap,
1188 UINT32 max_data_len,
1189 UINT32 *p_data_len,
1190 UINT8 *p_data)
1191 {
1192 tLLCP_DLCB *p_dlcb;
1193 BT_HDR *p_buf;
1194 UINT8 *p_i_pdu;
1195 UINT16 i_pdu_length;
1196
1197 LLCP_TRACE_API2 ("LLCP_ReadDataLinkData () Local SAP:0x%x, Remote SAP:0x%x",
1198 local_sap, remote_sap);
1199
1200 p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1201
1202 *p_data_len = 0;
1203 if (p_dlcb)
1204 {
1205 /* if any I PDU in rx queue */
1206 if (p_dlcb->i_rx_q.p_first)
1207 {
1208 p_buf = (BT_HDR *) p_dlcb->i_rx_q.p_first;
1209 p_i_pdu = (UINT8*) (p_buf + 1) + p_buf->offset;
1210
1211 /* get length of I PDU */
1212 BE_STREAM_TO_UINT16 (i_pdu_length, p_i_pdu);
1213
1214 /* layer_specific has the offset to read within I PDU */
1215 p_i_pdu += p_buf->layer_specific;
1216
1217 /* copy data up to max_data_len */
1218 if (max_data_len >= (UINT32) (i_pdu_length - p_buf->layer_specific))
1219 {
1220 /* copy information */
1221 *p_data_len = (UINT32) (i_pdu_length - p_buf->layer_specific);
1222
1223 /* move to next I PDU if any */
1224 p_buf->layer_specific = 0; /* reset offset to read from the first byte of next I PDU */
1225 p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
1226 p_buf->len -= LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
1227 }
1228 else
1229 {
1230 *p_data_len = max_data_len;
1231
1232 /* update offset to read from remaining I PDU next time */
1233 p_buf->layer_specific += max_data_len;
1234 }
1235
1236 memcpy (p_data, p_i_pdu, *p_data_len);
1237
1238 if (p_buf->layer_specific == 0)
1239 {
1240 p_dlcb->num_rx_i_pdu--;
1241 }
1242
1243 /* if read all of I PDU */
1244 if (p_buf->len == 0)
1245 {
1246 GKI_dequeue (&p_dlcb->i_rx_q);
1247 GKI_freebuf (p_buf);
1248
1249 /* decrease number of received I PDU in in all of ui_rx_q and check rx congestion status */
1250 llcp_cb.total_rx_i_pdu--;
1251 llcp_util_check_rx_congested_status ();
1252 }
1253 }
1254
1255 /* if getting out of rx congestion */
1256 if ( (!p_dlcb->local_busy)
1257 &&(p_dlcb->is_rx_congested)
1258 &&(p_dlcb->num_rx_i_pdu <= p_dlcb->rx_congest_threshold / 2) )
1259 {
1260 /* send RR */
1261 p_dlcb->is_rx_congested = FALSE;
1262 p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
1263 }
1264
1265 /* if there is more I PDU in rx queue */
1266 if (p_dlcb->i_rx_q.p_first)
1267 {
1268 return (TRUE);
1269 }
1270 else
1271 {
1272 return (FALSE);
1273 }
1274 }
1275 else
1276 {
1277 LLCP_TRACE_ERROR0 ("LLCP_ReadDataLinkData (): No data link connection");
1278
1279 return (FALSE);
1280 }
1281 }
1282
1283 /*******************************************************************************
1284 **
1285 ** Function LLCP_FlushDataLinkRxData
1286 **
1287 ** Description Discard received data in data link connection
1288 **
1289 **
1290 ** Returns length of rx data flushed
1291 **
1292 *******************************************************************************/
LLCP_FlushDataLinkRxData(UINT8 local_sap,UINT8 remote_sap)1293 UINT32 LLCP_FlushDataLinkRxData (UINT8 local_sap,
1294 UINT8 remote_sap)
1295 {
1296 tLLCP_DLCB *p_dlcb;
1297 BT_HDR *p_buf;
1298 UINT32 flushed_length = 0;
1299 UINT8 *p_i_pdu;
1300 UINT16 i_pdu_length;
1301
1302 LLCP_TRACE_API2 ("LLCP_FlushDataLinkRxData () Local SAP:0x%x, Remote SAP:0x%x",
1303 local_sap, remote_sap);
1304
1305 p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1306
1307 if (p_dlcb)
1308 {
1309 /* if any I PDU in rx queue */
1310 while (p_dlcb->i_rx_q.p_first)
1311 {
1312 p_buf = (BT_HDR *) p_dlcb->i_rx_q.p_first;
1313 p_i_pdu = (UINT8*) (p_buf + 1) + p_buf->offset;
1314
1315 /* get length of I PDU */
1316 BE_STREAM_TO_UINT16 (i_pdu_length, p_i_pdu);
1317
1318 flushed_length += (UINT32) (i_pdu_length - p_buf->layer_specific);
1319
1320 /* move to next I PDU if any */
1321 p_buf->layer_specific = 0; /* offset */
1322 p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
1323 p_buf->len -= LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
1324
1325 /* if read all of I PDU */
1326 if (p_buf->len == 0)
1327 {
1328 GKI_dequeue (&p_dlcb->i_rx_q);
1329 GKI_freebuf (p_buf);
1330 llcp_cb.total_rx_i_pdu--;
1331 }
1332 }
1333
1334 p_dlcb->num_rx_i_pdu = 0;
1335
1336 /* if getting out of rx congestion */
1337 if ( (!p_dlcb->local_busy)
1338 &&(p_dlcb->is_rx_congested) )
1339 {
1340 /* send RR */
1341 p_dlcb->is_rx_congested = FALSE;
1342 p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
1343 }
1344
1345 /* number of received I PDU is decreased so check rx congestion status */
1346 llcp_util_check_rx_congested_status ();
1347 }
1348 else
1349 {
1350 LLCP_TRACE_ERROR0 ("LLCP_FlushDataLinkRxData (): No data link connection");
1351 }
1352
1353 return (flushed_length);
1354 }
1355
1356 /*******************************************************************************
1357 **
1358 ** Function LLCP_DisconnectReq
1359 **
1360 ** Description Disconnect data link
1361 ** discard any pending data if flush is set to TRUE
1362 **
1363 ** Returns LLCP_STATUS_SUCCESS if success
1364 **
1365 *******************************************************************************/
LLCP_DisconnectReq(UINT8 local_sap,UINT8 remote_sap,BOOLEAN flush)1366 tLLCP_STATUS LLCP_DisconnectReq (UINT8 local_sap,
1367 UINT8 remote_sap,
1368 BOOLEAN flush)
1369 {
1370 tLLCP_STATUS status;
1371 tLLCP_DLCB *p_dlcb;
1372
1373 LLCP_TRACE_API3 ("LLCP_DisconnectReq () Local SAP:0x%x, Remote SAP:0x%x, flush=%d",
1374 local_sap, remote_sap, flush);
1375
1376 p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1377
1378 if (p_dlcb)
1379 {
1380 status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
1381 }
1382 else
1383 {
1384 LLCP_TRACE_ERROR0 ("LLCP_DisconnectReq (): No data link");
1385 status = LLCP_STATUS_FAIL;
1386 }
1387
1388 return status;
1389 }
1390
1391 /*******************************************************************************
1392 **
1393 ** Function LLCP_SetTxCompleteNtf
1394 **
1395 ** Description This function is called to get LLCP_SERVICE_TX_COMPLETE
1396 ** when Tx queue is empty and all PDU is acked.
1397 ** This is one time event, so upper layer shall call this function
1398 ** again to get next LLCP_SERVICE_TX_COMPLETE.
1399 **
1400 ** Returns LLCP_STATUS_SUCCESS if success
1401 **
1402 *******************************************************************************/
LLCP_SetTxCompleteNtf(UINT8 local_sap,UINT8 remote_sap)1403 tLLCP_STATUS LLCP_SetTxCompleteNtf (UINT8 local_sap,
1404 UINT8 remote_sap)
1405 {
1406 tLLCP_STATUS status;
1407 tLLCP_DLCB *p_dlcb;
1408
1409 LLCP_TRACE_API2 ("LLCP_SetTxCompleteNtf () Local SAP:0x%x, Remote SAP:0x%x",
1410 local_sap, remote_sap);
1411
1412 p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1413
1414 if (p_dlcb)
1415 {
1416 /* set flag to notify upper later when tx complete */
1417 p_dlcb->flags |= LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE;
1418 status = LLCP_STATUS_SUCCESS;
1419 }
1420 else
1421 {
1422 LLCP_TRACE_ERROR0 ("LLCP_SetTxCompleteNtf (): No data link");
1423 status = LLCP_STATUS_FAIL;
1424 }
1425
1426 return status;
1427 }
1428
1429 /*******************************************************************************
1430 **
1431 ** Function LLCP_SetLocalBusyStatus
1432 **
1433 ** Description Set local busy status
1434 **
1435 **
1436 ** Returns LLCP_STATUS_SUCCESS if success
1437 **
1438 *******************************************************************************/
LLCP_SetLocalBusyStatus(UINT8 local_sap,UINT8 remote_sap,BOOLEAN is_busy)1439 tLLCP_STATUS LLCP_SetLocalBusyStatus (UINT8 local_sap,
1440 UINT8 remote_sap,
1441 BOOLEAN is_busy)
1442 {
1443 tLLCP_STATUS status;
1444 tLLCP_DLCB *p_dlcb;
1445
1446 LLCP_TRACE_API2 ("LLCP_SetLocalBusyStatus () Local SAP:0x%x, is_busy=%d",
1447 local_sap, is_busy);
1448
1449 p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1450
1451 if (p_dlcb)
1452 {
1453 if (p_dlcb->local_busy != is_busy)
1454 {
1455 p_dlcb->local_busy = is_busy;
1456
1457 /* send RR or RNR with valid sequence */
1458 p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
1459
1460 if (is_busy == FALSE)
1461 {
1462 if (p_dlcb->i_rx_q.count)
1463 {
1464 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DATA_IND, NULL);
1465 }
1466 }
1467 }
1468 status = LLCP_STATUS_SUCCESS;
1469 }
1470 else
1471 {
1472 LLCP_TRACE_ERROR0 ("LLCP_SetLocalBusyStatus (): No data link");
1473 status = LLCP_STATUS_FAIL;
1474 }
1475
1476 return status;
1477 }
1478
1479 /*******************************************************************************
1480 **
1481 ** Function LLCP_GetRemoteWKS
1482 **
1483 ** Description Return well-known service bitmap of connected device
1484 **
1485 **
1486 ** Returns WKS bitmap if success
1487 **
1488 *******************************************************************************/
LLCP_GetRemoteWKS(void)1489 UINT16 LLCP_GetRemoteWKS (void)
1490 {
1491 LLCP_TRACE_API1 ("LLCP_GetRemoteWKS () WKS:0x%04x",
1492 (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED) ? llcp_cb.lcb.peer_wks :0);
1493
1494 if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
1495 return (llcp_cb.lcb.peer_wks);
1496 else
1497 return (0);
1498 }
1499
1500 /*******************************************************************************
1501 **
1502 ** Function LLCP_GetRemoteLSC
1503 **
1504 ** Description Return link service class of connected device
1505 **
1506 **
1507 ** Returns link service class
1508 **
1509 *******************************************************************************/
LLCP_GetRemoteLSC(void)1510 UINT8 LLCP_GetRemoteLSC (void)
1511 {
1512 LLCP_TRACE_API1 ("LLCP_GetRemoteLSC () LSC:0x%x",
1513 (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
1514 ? llcp_cb.lcb.peer_opt & (LLCP_LSC_1 | LLCP_LSC_2) :0);
1515
1516 if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
1517 return (llcp_cb.lcb.peer_opt & (LLCP_LSC_1 | LLCP_LSC_2));
1518 else
1519 return (LLCP_LSC_UNKNOWN);
1520 }
1521
1522 /*******************************************************************************
1523 **
1524 ** Function LLCP_GetLinkMIU
1525 **
1526 ** Description Return local and remote link MIU
1527 **
1528 **
1529 ** Returns None
1530 **
1531 *******************************************************************************/
LLCP_GetLinkMIU(UINT16 * p_local_link_miu,UINT16 * p_remote_link_miu)1532 LLCP_API void LLCP_GetLinkMIU (UINT16 *p_local_link_miu,
1533 UINT16 *p_remote_link_miu)
1534 {
1535 LLCP_TRACE_API0 ("LLCP_GetLinkMIU ()");
1536
1537 if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
1538 {
1539 *p_local_link_miu = llcp_cb.lcb.local_link_miu;
1540 *p_remote_link_miu = llcp_cb.lcb.effective_miu;
1541 }
1542 else
1543 {
1544 *p_local_link_miu = 0;
1545 *p_remote_link_miu = 0;
1546 }
1547
1548 LLCP_TRACE_DEBUG2 ("LLCP_GetLinkMIU (): local_link_miu = %d, remote_link_miu = %d",
1549 *p_local_link_miu, *p_remote_link_miu);
1550 }
1551
1552 /*******************************************************************************
1553 **
1554 ** Function LLCP_DiscoverService
1555 **
1556 ** Description Return SAP of service name in connected device through callback
1557 **
1558 **
1559 ** Returns LLCP_STATUS_SUCCESS if success
1560 **
1561 *******************************************************************************/
LLCP_DiscoverService(char * p_name,tLLCP_SDP_CBACK * p_cback,UINT8 * p_tid)1562 tLLCP_STATUS LLCP_DiscoverService (char *p_name,
1563 tLLCP_SDP_CBACK *p_cback,
1564 UINT8 *p_tid)
1565 {
1566 tLLCP_STATUS status;
1567 UINT8 i;
1568
1569 LLCP_TRACE_API1 ("LLCP_DiscoverService () Service Name:%s",
1570 p_name);
1571
1572 if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_ACTIVATED)
1573 {
1574 LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Link is not activated");
1575 return LLCP_STATUS_FAIL;
1576 }
1577
1578 if (!p_cback)
1579 {
1580 LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Callback must be provided.");
1581 return LLCP_STATUS_FAIL;
1582 }
1583
1584 /* if peer version is less than V1.1 then SNL is not supported */
1585 if ((llcp_cb.lcb.agreed_major_version == 0x01) && (llcp_cb.lcb.agreed_minor_version < 0x01))
1586 {
1587 LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Peer doesn't support SNL");
1588 return LLCP_STATUS_FAIL;
1589 }
1590
1591 for (i = 0; i < LLCP_MAX_SDP_TRANSAC; i++)
1592 {
1593 if (!llcp_cb.sdp_cb.transac[i].p_cback)
1594 {
1595 llcp_cb.sdp_cb.transac[i].tid = llcp_cb.sdp_cb.next_tid;
1596 llcp_cb.sdp_cb.next_tid++;
1597 llcp_cb.sdp_cb.transac[i].p_cback = p_cback;
1598
1599 status = llcp_sdp_send_sdreq (llcp_cb.sdp_cb.transac[i].tid, p_name);
1600
1601 if (status == LLCP_STATUS_FAIL)
1602 {
1603 llcp_cb.sdp_cb.transac[i].p_cback = NULL;
1604 }
1605
1606 *p_tid = llcp_cb.sdp_cb.transac[i].tid;
1607 return (status);
1608 }
1609 }
1610
1611 LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Out of resource");
1612
1613 return LLCP_STATUS_FAIL;
1614 }
1615
1616