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