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