1 /******************************************************************************
2 *
3 * Copyright (C) 2010-2014 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 tLLCP_CONNECTION_PARAMS params;
912
913 LLCP_TRACE_API2 ("LLCP_ConnectReq () reg_sap=0x%x, DSAP=0x%x", reg_sap, dsap);
914
915 if ( (llcp_cb.lcb.peer_opt != LLCP_LSC_UNKNOWN)
916 &&((llcp_cb.lcb.peer_opt & LLCP_LSC_2) == 0) )
917 {
918 LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): Peer doesn't support connection-oriented link");
919 return LLCP_STATUS_FAIL;
920 }
921
922 if (!p_params)
923 {
924 params.miu = LLCP_DEFAULT_MIU;
925 params.rw = LLCP_DEFAULT_RW;
926 params.sn[0] = 0;
927 p_params = ¶ms;
928 }
929
930 p_app_cb = llcp_util_get_app_cb (reg_sap);
931
932 /* if application is registered */
933 if ( (p_app_cb == NULL)
934 ||(p_app_cb->p_app_cback == NULL) )
935 {
936 LLCP_TRACE_ERROR1 ("LLCP_ConnectReq (): SSAP (0x%x) is not registered", reg_sap);
937 return LLCP_STATUS_FAIL;
938 }
939
940 if (dsap == LLCP_SAP_LM)
941 {
942 LLCP_TRACE_ERROR1 ("LLCP_ConnectReq (): DSAP (0x%x) must not be link manager SAP", dsap);
943 return LLCP_STATUS_FAIL;
944 }
945
946 if (dsap == LLCP_SAP_SDP)
947 {
948 if (strlen (p_params->sn) > LLCP_MAX_SN_LEN)
949 {
950 LLCP_TRACE_ERROR1 ("LLCP_ConnectReq (): Service Name (%d bytes) is too long",
951 strlen (p_params->sn));
952 return LLCP_STATUS_FAIL;
953 }
954 }
955
956 if ((p_params) && (p_params->miu > llcp_cb.lcb.local_link_miu))
957 {
958 LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): Data link MIU shall not be bigger than local link MIU");
959 return LLCP_STATUS_FAIL;
960 }
961
962 /* check if any pending connection request on this reg_sap */
963 p_dlcb = llcp_dlc_find_dlcb_by_sap (reg_sap, LLCP_INVALID_SAP);
964 if (p_dlcb)
965 {
966 /*
967 ** Accepting LLCP may change SAP in CC, so we cannot find right data link connection
968 ** if there is multiple pending connection request on the same local SAP.
969 */
970 LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): There is pending connect request on this reg_sap");
971 return LLCP_STATUS_FAIL;
972 }
973
974 p_dlcb = llcp_util_allocate_data_link (reg_sap, dsap);
975
976 if (p_dlcb)
977 {
978 status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_CONNECT_REQ, p_params);
979 if (status != LLCP_STATUS_SUCCESS)
980 {
981 LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): Error in state machine");
982 llcp_util_deallocate_data_link (p_dlcb);
983 return LLCP_STATUS_FAIL;
984 }
985 }
986 else
987 {
988 return LLCP_STATUS_FAIL;
989 }
990
991 return LLCP_STATUS_SUCCESS;
992 }
993
994 /*******************************************************************************
995 **
996 ** Function LLCP_ConnectCfm
997 **
998 ** Description Accept connection request from peer LLCP
999 **
1000 **
1001 ** Returns LLCP_STATUS_SUCCESS if success
1002 ** LLCP_STATUS_FAIL, otherwise
1003 **
1004 *******************************************************************************/
LLCP_ConnectCfm(UINT8 local_sap,UINT8 remote_sap,tLLCP_CONNECTION_PARAMS * p_params)1005 tLLCP_STATUS LLCP_ConnectCfm (UINT8 local_sap,
1006 UINT8 remote_sap,
1007 tLLCP_CONNECTION_PARAMS *p_params)
1008 {
1009 tLLCP_STATUS status;
1010 tLLCP_DLCB *p_dlcb;
1011 tLLCP_CONNECTION_PARAMS params;
1012
1013 LLCP_TRACE_API2 ("LLCP_ConnectCfm () Local SAP:0x%x, Remote SAP:0x%x)",
1014 local_sap, remote_sap);
1015
1016 if (!p_params)
1017 {
1018 params.miu = LLCP_DEFAULT_MIU;
1019 params.rw = LLCP_DEFAULT_RW;
1020 params.sn[0] = 0;
1021 p_params = ¶ms;
1022 }
1023 if (p_params->miu > llcp_cb.lcb.local_link_miu)
1024 {
1025 LLCP_TRACE_ERROR0 ("LLCP_ConnectCfm (): Data link MIU shall not be bigger than local link MIU");
1026 return LLCP_STATUS_FAIL;
1027 }
1028
1029 p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1030
1031 if (p_dlcb)
1032 {
1033 status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_CONNECT_CFM, p_params);
1034 }
1035 else
1036 {
1037 LLCP_TRACE_ERROR0 ("LLCP_ConnectCfm (): No data link");
1038 status = LLCP_STATUS_FAIL;
1039 }
1040
1041 return status;
1042 }
1043
1044 /*******************************************************************************
1045 **
1046 ** Function LLCP_ConnectReject
1047 **
1048 ** Description Reject connection request from peer LLCP
1049 **
1050 ** reason : LLCP_SAP_DM_REASON_APP_REJECTED
1051 ** LLCP_SAP_DM_REASON_PERM_REJECT_THIS
1052 ** LLCP_SAP_DM_REASON_PERM_REJECT_ANY
1053 ** LLCP_SAP_DM_REASON_TEMP_REJECT_THIS
1054 ** LLCP_SAP_DM_REASON_TEMP_REJECT_ANY
1055 **
1056 ** Returns LLCP_STATUS_SUCCESS if success
1057 ** LLCP_STATUS_FAIL, otherwise
1058 **
1059 *******************************************************************************/
LLCP_ConnectReject(UINT8 local_sap,UINT8 remote_sap,UINT8 reason)1060 tLLCP_STATUS LLCP_ConnectReject (UINT8 local_sap,
1061 UINT8 remote_sap,
1062 UINT8 reason)
1063 {
1064 tLLCP_STATUS status;
1065 tLLCP_DLCB *p_dlcb;
1066
1067 LLCP_TRACE_API3 ("LLCP_ConnectReject () Local SAP:0x%x, Remote SAP:0x%x, reason:0x%x",
1068 local_sap, remote_sap, reason);
1069
1070 p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1071
1072 if (p_dlcb)
1073 {
1074 status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_CONNECT_REJECT, &reason);
1075 llcp_util_deallocate_data_link (p_dlcb);
1076 }
1077 else
1078 {
1079 LLCP_TRACE_ERROR0 ("LLCP_ConnectReject (): No data link");
1080 status = LLCP_STATUS_FAIL;
1081 }
1082
1083 return status;
1084 }
1085
1086 /*******************************************************************************
1087 **
1088 ** Function LLCP_IsDataLinkCongested
1089 **
1090 ** Description Check if data link connection is congested
1091 **
1092 **
1093 ** Returns TRUE if congested
1094 **
1095 *******************************************************************************/
LLCP_IsDataLinkCongested(UINT8 local_sap,UINT8 remote_sap,UINT8 num_pending_i_pdu,UINT8 total_pending_ui_pdu,UINT8 total_pending_i_pdu)1096 BOOLEAN LLCP_IsDataLinkCongested (UINT8 local_sap,
1097 UINT8 remote_sap,
1098 UINT8 num_pending_i_pdu,
1099 UINT8 total_pending_ui_pdu,
1100 UINT8 total_pending_i_pdu)
1101 {
1102 tLLCP_DLCB *p_dlcb;
1103
1104 LLCP_TRACE_API5 ("LLCP_IsDataLinkCongested () Local SAP:0x%x, Remote SAP:0x%x, pending = (%d, %d, %d)",
1105 local_sap, remote_sap, num_pending_i_pdu, total_pending_ui_pdu, total_pending_i_pdu);
1106
1107 p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1108
1109 if (p_dlcb)
1110 {
1111 if ( (p_dlcb->is_tx_congested)
1112 ||(p_dlcb->remote_busy) )
1113 {
1114 return (TRUE);
1115 }
1116 else if ( (num_pending_i_pdu + p_dlcb->i_xmit_q.count >= p_dlcb->remote_rw)
1117 ||(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) )
1118 {
1119 /* set flag so LLCP can notify uncongested status later */
1120 p_dlcb->is_tx_congested = TRUE;
1121 return (TRUE);
1122 }
1123 return (FALSE);
1124 }
1125 return (TRUE);
1126 }
1127
1128 /*******************************************************************************
1129 **
1130 ** Function LLCP_SendData
1131 **
1132 ** Description Send connection-oriented data
1133 **
1134 **
1135 ** Returns LLCP_STATUS_SUCCESS if success
1136 ** LLCP_STATUS_CONGESTED if data link is congested
1137 **
1138 *******************************************************************************/
LLCP_SendData(UINT8 local_sap,UINT8 remote_sap,BT_HDR * p_buf)1139 tLLCP_STATUS LLCP_SendData (UINT8 local_sap,
1140 UINT8 remote_sap,
1141 BT_HDR *p_buf)
1142 {
1143 tLLCP_STATUS status = LLCP_STATUS_FAIL;
1144 tLLCP_DLCB *p_dlcb;
1145
1146 LLCP_TRACE_API2 ("LLCP_SendData () Local SAP:0x%x, Remote SAP:0x%x",
1147 local_sap, remote_sap);
1148
1149 p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1150
1151 if (p_dlcb)
1152 {
1153 if (p_dlcb->remote_miu >= p_buf->len)
1154 {
1155 if (p_buf->offset >= LLCP_MIN_OFFSET)
1156 {
1157 status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DATA_REQ, p_buf);
1158 }
1159 else
1160 {
1161 LLCP_TRACE_ERROR2 ("LLCP_SendData (): offset (%d) must be %d at least",
1162 p_buf->offset, LLCP_MIN_OFFSET );
1163 }
1164 }
1165 else
1166 {
1167 LLCP_TRACE_ERROR2 ("LLCP_SendData (): Information (%d bytes) cannot be more than peer MIU (%d bytes)",
1168 p_buf->len, p_dlcb->remote_miu);
1169 }
1170 }
1171 else
1172 {
1173 LLCP_TRACE_ERROR0 ("LLCP_SendData (): No data link");
1174 }
1175
1176 if (status == LLCP_STATUS_FAIL)
1177 {
1178 GKI_freebuf (p_buf);
1179 }
1180
1181 return status;
1182 }
1183
1184 /*******************************************************************************
1185 **
1186 ** Function LLCP_ReadDataLinkData
1187 **
1188 ** Description Read information of I PDU for data link connection
1189 **
1190 ** - Information of I PDU up to max_data_len is copied into p_data.
1191 ** - Information of next I PDU is not concatenated.
1192 ** - Recommended max_data_len is data link connection MIU of local
1193 ** end point
1194 **
1195 ** Returns TRUE if more data in queue
1196 **
1197 *******************************************************************************/
LLCP_ReadDataLinkData(UINT8 local_sap,UINT8 remote_sap,UINT32 max_data_len,UINT32 * p_data_len,UINT8 * p_data)1198 BOOLEAN LLCP_ReadDataLinkData (UINT8 local_sap,
1199 UINT8 remote_sap,
1200 UINT32 max_data_len,
1201 UINT32 *p_data_len,
1202 UINT8 *p_data)
1203 {
1204 tLLCP_DLCB *p_dlcb;
1205 BT_HDR *p_buf;
1206 UINT8 *p_i_pdu;
1207 UINT16 i_pdu_length;
1208
1209 LLCP_TRACE_API2 ("LLCP_ReadDataLinkData () Local SAP:0x%x, Remote SAP:0x%x",
1210 local_sap, remote_sap);
1211
1212 p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1213
1214 *p_data_len = 0;
1215 if (p_dlcb)
1216 {
1217 /* if any I PDU in rx queue */
1218 if (p_dlcb->i_rx_q.p_first)
1219 {
1220 p_buf = (BT_HDR *) p_dlcb->i_rx_q.p_first;
1221 p_i_pdu = (UINT8*) (p_buf + 1) + p_buf->offset;
1222
1223 /* get length of I PDU */
1224 BE_STREAM_TO_UINT16 (i_pdu_length, p_i_pdu);
1225
1226 /* layer_specific has the offset to read within I PDU */
1227 p_i_pdu += p_buf->layer_specific;
1228
1229 /* copy data up to max_data_len */
1230 if (max_data_len >= (UINT32) (i_pdu_length - p_buf->layer_specific))
1231 {
1232 /* copy information */
1233 *p_data_len = (UINT32) (i_pdu_length - p_buf->layer_specific);
1234
1235 /* move to next I PDU if any */
1236 p_buf->layer_specific = 0; /* reset offset to read from the first byte of next I PDU */
1237 p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
1238 p_buf->len -= LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
1239 }
1240 else
1241 {
1242 *p_data_len = max_data_len;
1243
1244 /* update offset to read from remaining I PDU next time */
1245 p_buf->layer_specific += max_data_len;
1246 }
1247
1248 memcpy (p_data, p_i_pdu, *p_data_len);
1249
1250 if (p_buf->layer_specific == 0)
1251 {
1252 p_dlcb->num_rx_i_pdu--;
1253 }
1254
1255 /* if read all of I PDU */
1256 if (p_buf->len == 0)
1257 {
1258 GKI_dequeue (&p_dlcb->i_rx_q);
1259 GKI_freebuf (p_buf);
1260
1261 /* decrease number of received I PDU in in all of ui_rx_q and check rx congestion status */
1262 llcp_cb.total_rx_i_pdu--;
1263 llcp_util_check_rx_congested_status ();
1264 }
1265 }
1266
1267 /* if getting out of rx congestion */
1268 if ( (!p_dlcb->local_busy)
1269 &&(p_dlcb->is_rx_congested)
1270 &&(p_dlcb->num_rx_i_pdu <= p_dlcb->rx_congest_threshold / 2) )
1271 {
1272 /* send RR */
1273 p_dlcb->is_rx_congested = FALSE;
1274 p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
1275 }
1276
1277 /* if there is more I PDU in rx queue */
1278 if (p_dlcb->i_rx_q.p_first)
1279 {
1280 return (TRUE);
1281 }
1282 else
1283 {
1284 return (FALSE);
1285 }
1286 }
1287 else
1288 {
1289 LLCP_TRACE_ERROR0 ("LLCP_ReadDataLinkData (): No data link connection");
1290
1291 return (FALSE);
1292 }
1293 }
1294
1295 /*******************************************************************************
1296 **
1297 ** Function LLCP_FlushDataLinkRxData
1298 **
1299 ** Description Discard received data in data link connection
1300 **
1301 **
1302 ** Returns length of rx data flushed
1303 **
1304 *******************************************************************************/
LLCP_FlushDataLinkRxData(UINT8 local_sap,UINT8 remote_sap)1305 UINT32 LLCP_FlushDataLinkRxData (UINT8 local_sap,
1306 UINT8 remote_sap)
1307 {
1308 tLLCP_DLCB *p_dlcb;
1309 BT_HDR *p_buf;
1310 UINT32 flushed_length = 0;
1311 UINT8 *p_i_pdu;
1312 UINT16 i_pdu_length;
1313
1314 LLCP_TRACE_API2 ("LLCP_FlushDataLinkRxData () Local SAP:0x%x, Remote SAP:0x%x",
1315 local_sap, remote_sap);
1316
1317 p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1318
1319 if (p_dlcb)
1320 {
1321 /* if any I PDU in rx queue */
1322 while (p_dlcb->i_rx_q.p_first)
1323 {
1324 p_buf = (BT_HDR *) p_dlcb->i_rx_q.p_first;
1325 p_i_pdu = (UINT8*) (p_buf + 1) + p_buf->offset;
1326
1327 /* get length of I PDU */
1328 BE_STREAM_TO_UINT16 (i_pdu_length, p_i_pdu);
1329
1330 flushed_length += (UINT32) (i_pdu_length - p_buf->layer_specific);
1331
1332 /* move to next I PDU if any */
1333 p_buf->layer_specific = 0; /* offset */
1334 p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
1335 p_buf->len -= LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
1336
1337 /* if read all of I PDU */
1338 if (p_buf->len == 0)
1339 {
1340 GKI_dequeue (&p_dlcb->i_rx_q);
1341 GKI_freebuf (p_buf);
1342 llcp_cb.total_rx_i_pdu--;
1343 }
1344 }
1345
1346 p_dlcb->num_rx_i_pdu = 0;
1347
1348 /* if getting out of rx congestion */
1349 if ( (!p_dlcb->local_busy)
1350 &&(p_dlcb->is_rx_congested) )
1351 {
1352 /* send RR */
1353 p_dlcb->is_rx_congested = FALSE;
1354 p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
1355 }
1356
1357 /* number of received I PDU is decreased so check rx congestion status */
1358 llcp_util_check_rx_congested_status ();
1359 }
1360 else
1361 {
1362 LLCP_TRACE_ERROR0 ("LLCP_FlushDataLinkRxData (): No data link connection");
1363 }
1364
1365 return (flushed_length);
1366 }
1367
1368 /*******************************************************************************
1369 **
1370 ** Function LLCP_DisconnectReq
1371 **
1372 ** Description Disconnect data link
1373 ** discard any pending data if flush is set to TRUE
1374 **
1375 ** Returns LLCP_STATUS_SUCCESS if success
1376 **
1377 *******************************************************************************/
LLCP_DisconnectReq(UINT8 local_sap,UINT8 remote_sap,BOOLEAN flush)1378 tLLCP_STATUS LLCP_DisconnectReq (UINT8 local_sap,
1379 UINT8 remote_sap,
1380 BOOLEAN flush)
1381 {
1382 tLLCP_STATUS status;
1383 tLLCP_DLCB *p_dlcb;
1384
1385 LLCP_TRACE_API3 ("LLCP_DisconnectReq () Local SAP:0x%x, Remote SAP:0x%x, flush=%d",
1386 local_sap, remote_sap, flush);
1387
1388 p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1389
1390 if (p_dlcb)
1391 {
1392 status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
1393 }
1394 else
1395 {
1396 LLCP_TRACE_ERROR0 ("LLCP_DisconnectReq (): No data link");
1397 status = LLCP_STATUS_FAIL;
1398 }
1399
1400 return status;
1401 }
1402
1403 /*******************************************************************************
1404 **
1405 ** Function LLCP_SetTxCompleteNtf
1406 **
1407 ** Description This function is called to get LLCP_SERVICE_TX_COMPLETE
1408 ** when Tx queue is empty and all PDU is acked.
1409 ** This is one time event, so upper layer shall call this function
1410 ** again to get next LLCP_SERVICE_TX_COMPLETE.
1411 **
1412 ** Returns LLCP_STATUS_SUCCESS if success
1413 **
1414 *******************************************************************************/
LLCP_SetTxCompleteNtf(UINT8 local_sap,UINT8 remote_sap)1415 tLLCP_STATUS LLCP_SetTxCompleteNtf (UINT8 local_sap,
1416 UINT8 remote_sap)
1417 {
1418 tLLCP_STATUS status;
1419 tLLCP_DLCB *p_dlcb;
1420
1421 LLCP_TRACE_API2 ("LLCP_SetTxCompleteNtf () Local SAP:0x%x, Remote SAP:0x%x",
1422 local_sap, remote_sap);
1423
1424 p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1425
1426 if (p_dlcb)
1427 {
1428 /* set flag to notify upper later when tx complete */
1429 p_dlcb->flags |= LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE;
1430 status = LLCP_STATUS_SUCCESS;
1431 }
1432 else
1433 {
1434 LLCP_TRACE_ERROR0 ("LLCP_SetTxCompleteNtf (): No data link");
1435 status = LLCP_STATUS_FAIL;
1436 }
1437
1438 return status;
1439 }
1440
1441 /*******************************************************************************
1442 **
1443 ** Function LLCP_SetLocalBusyStatus
1444 **
1445 ** Description Set local busy status
1446 **
1447 **
1448 ** Returns LLCP_STATUS_SUCCESS if success
1449 **
1450 *******************************************************************************/
LLCP_SetLocalBusyStatus(UINT8 local_sap,UINT8 remote_sap,BOOLEAN is_busy)1451 tLLCP_STATUS LLCP_SetLocalBusyStatus (UINT8 local_sap,
1452 UINT8 remote_sap,
1453 BOOLEAN is_busy)
1454 {
1455 tLLCP_STATUS status;
1456 tLLCP_DLCB *p_dlcb;
1457
1458 LLCP_TRACE_API2 ("LLCP_SetLocalBusyStatus () Local SAP:0x%x, is_busy=%d",
1459 local_sap, is_busy);
1460
1461 p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1462
1463 if (p_dlcb)
1464 {
1465 if (p_dlcb->local_busy != is_busy)
1466 {
1467 p_dlcb->local_busy = is_busy;
1468
1469 /* send RR or RNR with valid sequence */
1470 p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
1471
1472 if (is_busy == FALSE)
1473 {
1474 if (p_dlcb->i_rx_q.count)
1475 {
1476 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DATA_IND, NULL);
1477 }
1478 }
1479 }
1480 status = LLCP_STATUS_SUCCESS;
1481 }
1482 else
1483 {
1484 LLCP_TRACE_ERROR0 ("LLCP_SetLocalBusyStatus (): No data link");
1485 status = LLCP_STATUS_FAIL;
1486 }
1487
1488 return status;
1489 }
1490
1491 /*******************************************************************************
1492 **
1493 ** Function LLCP_GetRemoteWKS
1494 **
1495 ** Description Return well-known service bitmap of connected device
1496 **
1497 **
1498 ** Returns WKS bitmap if success
1499 **
1500 *******************************************************************************/
LLCP_GetRemoteWKS(void)1501 UINT16 LLCP_GetRemoteWKS (void)
1502 {
1503 LLCP_TRACE_API1 ("LLCP_GetRemoteWKS () WKS:0x%04x",
1504 (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED) ? llcp_cb.lcb.peer_wks :0);
1505
1506 if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
1507 return (llcp_cb.lcb.peer_wks);
1508 else
1509 return (0);
1510 }
1511
1512 /*******************************************************************************
1513 **
1514 ** Function LLCP_GetRemoteLSC
1515 **
1516 ** Description Return link service class of connected device
1517 **
1518 **
1519 ** Returns link service class
1520 **
1521 *******************************************************************************/
LLCP_GetRemoteLSC(void)1522 UINT8 LLCP_GetRemoteLSC (void)
1523 {
1524 LLCP_TRACE_API1 ("LLCP_GetRemoteLSC () LSC:0x%x",
1525 (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
1526 ? llcp_cb.lcb.peer_opt & (LLCP_LSC_1 | LLCP_LSC_2) :0);
1527
1528 if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
1529 return (llcp_cb.lcb.peer_opt & (LLCP_LSC_1 | LLCP_LSC_2));
1530 else
1531 return (LLCP_LSC_UNKNOWN);
1532 }
1533
1534 /*******************************************************************************
1535 **
1536 ** Function LLCP_GetLinkMIU
1537 **
1538 ** Description Return local and remote link MIU
1539 **
1540 **
1541 ** Returns None
1542 **
1543 *******************************************************************************/
LLCP_GetLinkMIU(UINT16 * p_local_link_miu,UINT16 * p_remote_link_miu)1544 LLCP_API void LLCP_GetLinkMIU (UINT16 *p_local_link_miu,
1545 UINT16 *p_remote_link_miu)
1546 {
1547 LLCP_TRACE_API0 ("LLCP_GetLinkMIU ()");
1548
1549 if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
1550 {
1551 *p_local_link_miu = llcp_cb.lcb.local_link_miu;
1552 *p_remote_link_miu = llcp_cb.lcb.effective_miu;
1553 }
1554 else
1555 {
1556 *p_local_link_miu = 0;
1557 *p_remote_link_miu = 0;
1558 }
1559
1560 LLCP_TRACE_DEBUG2 ("LLCP_GetLinkMIU (): local_link_miu = %d, remote_link_miu = %d",
1561 *p_local_link_miu, *p_remote_link_miu);
1562 }
1563
1564 /*******************************************************************************
1565 **
1566 ** Function LLCP_DiscoverService
1567 **
1568 ** Description Return SAP of service name in connected device through callback
1569 **
1570 **
1571 ** Returns LLCP_STATUS_SUCCESS if success
1572 **
1573 *******************************************************************************/
LLCP_DiscoverService(char * p_name,tLLCP_SDP_CBACK * p_cback,UINT8 * p_tid)1574 tLLCP_STATUS LLCP_DiscoverService (char *p_name,
1575 tLLCP_SDP_CBACK *p_cback,
1576 UINT8 *p_tid)
1577 {
1578 tLLCP_STATUS status;
1579 UINT8 i;
1580
1581 LLCP_TRACE_API1 ("LLCP_DiscoverService () Service Name:%s",
1582 p_name);
1583
1584 if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_ACTIVATED)
1585 {
1586 LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Link is not activated");
1587 return LLCP_STATUS_FAIL;
1588 }
1589
1590 if (!p_cback)
1591 {
1592 LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Callback must be provided.");
1593 return LLCP_STATUS_FAIL;
1594 }
1595
1596 /* if peer version is less than V1.1 then SNL is not supported */
1597 if ((llcp_cb.lcb.agreed_major_version == 0x01) && (llcp_cb.lcb.agreed_minor_version < 0x01))
1598 {
1599 LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Peer doesn't support SNL");
1600 return LLCP_STATUS_FAIL;
1601 }
1602
1603 for (i = 0; i < LLCP_MAX_SDP_TRANSAC; i++)
1604 {
1605 if (!llcp_cb.sdp_cb.transac[i].p_cback)
1606 {
1607 llcp_cb.sdp_cb.transac[i].tid = llcp_cb.sdp_cb.next_tid;
1608 llcp_cb.sdp_cb.next_tid++;
1609 llcp_cb.sdp_cb.transac[i].p_cback = p_cback;
1610
1611 status = llcp_sdp_send_sdreq (llcp_cb.sdp_cb.transac[i].tid, p_name);
1612
1613 if (status == LLCP_STATUS_FAIL)
1614 {
1615 llcp_cb.sdp_cb.transac[i].p_cback = NULL;
1616 }
1617
1618 *p_tid = llcp_cb.sdp_cb.transac[i].tid;
1619 return (status);
1620 }
1621 }
1622
1623 LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Out of resource");
1624
1625 return LLCP_STATUS_FAIL;
1626 }
1627
1628