1/****************************************************************************** 2 * 3 * Copyright (C) 1999-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 L2CAP UCD code 22 * 23 ******************************************************************************/ 24 25#include <stdlib.h> 26#include <string.h> 27#include <stdio.h> 28 29#include "gki.h" 30#include "bt_types.h" 31#include "hcidefs.h" 32#include "hcimsgs.h" 33#include "l2cdefs.h" 34#include "l2c_int.h" 35#include "btu.h" 36#include "btm_api.h" 37#include "btm_int.h" 38 39#if (L2CAP_UCD_INCLUDED == TRUE) 40static BOOLEAN l2c_ucd_connect ( BD_ADDR rem_bda ); 41 42/******************************************************************************* 43** 44** Function l2c_ucd_discover_cback 45** 46** Description UCD Discover callback 47** 48** Returns void 49** 50*******************************************************************************/ 51static void l2c_ucd_discover_cback (BD_ADDR rem_bda, UINT8 info_type, UINT32 data) 52{ 53 tL2C_RCB *p_rcb = &l2cb.rcb_pool[0]; 54 UINT16 xx; 55 56 L2CAP_TRACE_DEBUG ("L2CAP - l2c_ucd_discover_cback"); 57 58 for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) 59 { 60 if (p_rcb->in_use) 61 { 62 /* if this application is waiting UCD reception info */ 63 if (( info_type == L2CAP_UCD_INFO_TYPE_RECEPTION ) 64 && ( p_rcb->ucd.state & L2C_UCD_STATE_W4_RECEPTION )) 65 { 66 p_rcb->ucd.cb_info.pL2CA_UCD_Discover_Cb (rem_bda, info_type, data); 67 p_rcb->ucd.state &= ~(L2C_UCD_STATE_W4_RECEPTION); 68 } 69 70 /* if this application is waiting UCD MTU info */ 71 if (( info_type == L2CAP_UCD_INFO_TYPE_MTU ) 72 && ( p_rcb->ucd.state & L2C_UCD_STATE_W4_MTU )) 73 { 74 p_rcb->ucd.cb_info.pL2CA_UCD_Discover_Cb (rem_bda, info_type, data); 75 p_rcb->ucd.state &= ~(L2C_UCD_STATE_W4_MTU); 76 } 77 } 78 } 79} 80 81/******************************************************************************* 82** 83** Function l2c_ucd_data_ind_cback 84** 85** Description UCD Data callback 86** 87** Returns void 88** 89*******************************************************************************/ 90static void l2c_ucd_data_ind_cback (BD_ADDR rem_bda, BT_HDR *p_buf) 91{ 92 UINT8 *p; 93 UINT16 psm; 94 tL2C_RCB *p_rcb; 95 96 L2CAP_TRACE_DEBUG ("L2CAP - l2c_ucd_data_ind_cback"); 97 98 p = (UINT8 *)(p_buf + 1) + p_buf->offset; 99 STREAM_TO_UINT16(psm, p) 100 101 p_buf->offset += L2CAP_UCD_OVERHEAD; 102 p_buf->len -= L2CAP_UCD_OVERHEAD; 103 104 if ((p_rcb = l2cu_find_rcb_by_psm (psm)) == NULL) 105 { 106 L2CAP_TRACE_ERROR ("L2CAP - no RCB for l2c_ucd_data_ind_cback, PSM: 0x%04x", psm); 107 GKI_freebuf (p_buf); 108 } 109 else 110 { 111 p_rcb->ucd.cb_info.pL2CA_UCD_Data_Cb(rem_bda, p_buf); 112 } 113} 114 115/******************************************************************************* 116** 117** Function l2c_ucd_congestion_status_cback 118** 119** Description UCD Congestion Status callback 120** 121** Returns void 122** 123*******************************************************************************/ 124static void l2c_ucd_congestion_status_cback (BD_ADDR rem_bda, BOOLEAN is_congested) 125{ 126 tL2C_RCB *p_rcb = &l2cb.rcb_pool[0]; 127 UINT16 xx; 128 129 L2CAP_TRACE_DEBUG ("L2CAP - l2c_ucd_congestion_status_cback"); 130 131 for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) 132 { 133 if (( p_rcb->in_use ) 134 &&( p_rcb->ucd.state != L2C_UCD_STATE_UNUSED )) 135 { 136 if ( p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb ) 137 { 138 L2CAP_TRACE_DEBUG ("L2CAP - Calling UCDCongestionStatus_Cb (%d), PSM=0x%04x, BDA: %08x%04x,", 139 is_congested, p_rcb->psm, 140 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], 141 (rem_bda[4]<<8)+rem_bda[5]); 142 143 p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb ( rem_bda, is_congested ); 144 } 145 } 146 } 147} 148 149/******************************************************************************* 150** 151** Function l2c_ucd_disconnect_ind_cback 152** 153** Description UCD disconnect callback (This prevent to access null pointer) 154** 155** Returns void 156** 157*******************************************************************************/ 158static void l2c_ucd_disconnect_ind_cback (UINT16 cid, BOOLEAN result) 159{ 160 /* do nothing */ 161} 162 163/******************************************************************************* 164** 165** Function l2c_ucd_config_ind_cback 166** 167** Description UCD config callback (This prevent to access null pointer) 168** 169** Returns void 170** 171*******************************************************************************/ 172static void l2c_ucd_config_ind_cback (UINT16 cid, tL2CAP_CFG_INFO *p_cfg) 173{ 174 /* do nothing */ 175} 176 177/******************************************************************************* 178** 179** Function l2c_ucd_config_cfm_cback 180** 181** Description UCD config callback (This prevent to access null pointer) 182** 183** Returns void 184** 185*******************************************************************************/ 186static void l2c_ucd_config_cfm_cback (UINT16 cid, tL2CAP_CFG_INFO *p_cfg) 187{ 188 /* do nothing */ 189} 190 191/******************************************************************************* 192** 193** Function L2CA_UcdRegister 194** 195** Description Register PSM on UCD. 196** 197** Parameters: tL2CAP_UCD_CB_INFO 198** 199** Return value: TRUE if successs 200** 201*******************************************************************************/ 202BOOLEAN L2CA_UcdRegister ( UINT16 psm, tL2CAP_UCD_CB_INFO *p_cb_info ) 203{ 204 tL2C_RCB *p_rcb; 205 206 L2CAP_TRACE_API ("L2CA_UcdRegister() PSM: 0x%04x", psm); 207 208 if ((!p_cb_info->pL2CA_UCD_Discover_Cb) 209 || (!p_cb_info->pL2CA_UCD_Data_Cb)) 210 { 211 L2CAP_TRACE_ERROR ("L2CAP - no callback registering PSM(0x%04x) on UCD", psm); 212 return (FALSE); 213 } 214 215 if ((p_rcb = l2cu_find_rcb_by_psm (psm)) == NULL) 216 { 217 L2CAP_TRACE_ERROR ("L2CAP - no RCB for L2CA_UcdRegister, PSM: 0x%04x", psm); 218 return (FALSE); 219 } 220 221 p_rcb->ucd.state = L2C_UCD_STATE_W4_DATA; 222 p_rcb->ucd.cb_info = *p_cb_info; 223 224 /* check if master rcb is created for UCD */ 225 if ((p_rcb = l2cu_find_rcb_by_psm (L2C_UCD_RCB_ID)) == NULL) 226 { 227 if ((p_rcb = l2cu_allocate_rcb (L2C_UCD_RCB_ID)) == NULL) 228 { 229 L2CAP_TRACE_ERROR ("L2CAP - no RCB available for L2CA_UcdRegister"); 230 return (FALSE); 231 } 232 else 233 { 234 /* these callback functions will forward data to each UCD application */ 235 p_rcb->ucd.cb_info.pL2CA_UCD_Discover_Cb = l2c_ucd_discover_cback; 236 p_rcb->ucd.cb_info.pL2CA_UCD_Data_Cb = l2c_ucd_data_ind_cback; 237 p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb = l2c_ucd_congestion_status_cback; 238 239 memset (&p_rcb->api, 0, sizeof(tL2CAP_APPL_INFO)); 240 p_rcb->api.pL2CA_DisconnectInd_Cb = l2c_ucd_disconnect_ind_cback; 241 242 /* This will make L2CAP check UCD congestion callback */ 243 p_rcb->api.pL2CA_CongestionStatus_Cb = NULL; 244 245 /* do nothing but prevent crash */ 246 p_rcb->api.pL2CA_ConfigInd_Cb = l2c_ucd_config_ind_cback; 247 p_rcb->api.pL2CA_ConfigCfm_Cb = l2c_ucd_config_cfm_cback; 248 } 249 } 250 251 return (TRUE); 252} 253 254/******************************************************************************* 255** 256** Function L2CA_UcdDeregister 257** 258** Description Deregister PSM on UCD. 259** 260** Parameters: PSM 261** 262** Return value: TRUE if successs 263** 264*******************************************************************************/ 265BOOLEAN L2CA_UcdDeregister ( UINT16 psm ) 266{ 267 tL2C_CCB *p_ccb; 268 tL2C_RCB *p_rcb; 269 UINT16 xx; 270 271 L2CAP_TRACE_API ("L2CA_UcdDeregister() PSM: 0x%04x", psm); 272 273 if ((p_rcb = l2cu_find_rcb_by_psm (psm)) == NULL) 274 { 275 L2CAP_TRACE_ERROR ("L2CAP - no RCB for L2CA_UcdDeregister, PSM: 0x%04x", psm); 276 return (FALSE); 277 } 278 279 p_rcb->ucd.state = L2C_UCD_STATE_UNUSED; 280 281 /* check this was the last UCD registration */ 282 p_rcb = &l2cb.rcb_pool[0]; 283 284 for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) 285 { 286 if ((p_rcb->in_use) && (p_rcb->ucd.state != L2C_UCD_STATE_UNUSED)) 287 return (TRUE); 288 } 289 290 /* delete master rcb for UCD */ 291 if ((p_rcb = l2cu_find_rcb_by_psm (L2C_UCD_RCB_ID)) != NULL) 292 { 293 l2cu_release_rcb (p_rcb); 294 } 295 296 /* delete CCB for UCD */ 297 p_ccb = l2cb.ccb_pool; 298 for ( xx = 0; xx < MAX_L2CAP_CHANNELS; xx++ ) 299 { 300 if (( p_ccb->in_use ) 301 &&( p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID )) 302 { 303 l2cu_release_ccb (p_ccb); 304 } 305 p_ccb++; 306 } 307 308 return (TRUE); 309} 310 311/******************************************************************************* 312** 313** Function L2CA_UcdDiscover 314** 315** Description Discover UCD of remote device. 316** 317** Parameters: PSM 318** BD_ADDR of remote device 319** info_type : L2CAP_UCD_INFO_TYPE_RECEPTION 320** L2CAP_UCD_INFO_TYPE_MTU 321** 322** 323** Return value: TRUE if successs 324** 325*******************************************************************************/ 326BOOLEAN L2CA_UcdDiscover ( UINT16 psm, BD_ADDR rem_bda, UINT8 info_type ) 327{ 328 tL2C_LCB *p_lcb; 329 tL2C_CCB *p_ccb; 330 tL2C_RCB *p_rcb; 331 332 L2CAP_TRACE_API ("L2CA_UcdDiscover() PSM: 0x%04x BDA: %08x%04x, InfoType=0x%02x", psm, 333 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], 334 (rem_bda[4]<<8)+rem_bda[5], info_type); 335 336 /* Fail if the PSM is not registered */ 337 if (((p_rcb = l2cu_find_rcb_by_psm (psm)) == NULL) 338 ||( p_rcb->ucd.state == L2C_UCD_STATE_UNUSED )) 339 { 340 L2CAP_TRACE_WARNING ("L2CAP - no RCB for L2CA_UcdDiscover, PSM: 0x%04x", psm); 341 return (FALSE); 342 } 343 344 /* First, see if we already have a link to the remote */ 345 /* then find the channel control block for UCD. */ 346 if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL) 347 ||((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL)) 348 { 349 if ( l2c_ucd_connect (rem_bda) == FALSE ) 350 { 351 return (FALSE); 352 } 353 } 354 355 /* set waiting flags in rcb */ 356 357 if ( info_type & L2CAP_UCD_INFO_TYPE_RECEPTION ) 358 p_rcb->ucd.state |= L2C_UCD_STATE_W4_RECEPTION; 359 360 if ( info_type & L2CAP_UCD_INFO_TYPE_MTU ) 361 p_rcb->ucd.state |= L2C_UCD_STATE_W4_MTU; 362 363 /* if link is already established */ 364 if ((p_lcb)&&(p_lcb->link_state == LST_CONNECTED)) 365 { 366 if (!p_ccb) 367 { 368 p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID); 369 } 370 l2c_ucd_check_pending_info_req(p_ccb); 371 } 372 return (TRUE); 373} 374 375/******************************************************************************* 376** 377** Function L2CA_UcdDataWrite 378** 379** Description Send UCD to remote device 380** 381** Parameters: PSM 382** BD Address of remote 383** Pointer to buffer of type BT_HDR 384** flags : L2CAP_FLUSHABLE_CH_BASED 385** L2CAP_FLUSHABLE_PKT 386** L2CAP_NON_FLUSHABLE_PKT 387** 388** Return value L2CAP_DW_SUCCESS, if data accepted 389** L2CAP_DW_FAILED, if error 390** 391*******************************************************************************/ 392UINT16 L2CA_UcdDataWrite (UINT16 psm, BD_ADDR rem_bda, BT_HDR *p_buf, UINT16 flags) 393{ 394 tL2C_LCB *p_lcb; 395 tL2C_CCB *p_ccb; 396 tL2C_RCB *p_rcb; 397 UINT8 *p; 398 399 L2CAP_TRACE_API ("L2CA_UcdDataWrite() PSM: 0x%04x BDA: %08x%04x", psm, 400 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], 401 (rem_bda[4]<<8)+rem_bda[5]); 402 403 /* Fail if the PSM is not registered */ 404 if (((p_rcb = l2cu_find_rcb_by_psm (psm)) == NULL) 405 ||( p_rcb->ucd.state == L2C_UCD_STATE_UNUSED )) 406 { 407 L2CAP_TRACE_WARNING ("L2CAP - no RCB for L2CA_UcdDataWrite, PSM: 0x%04x", psm); 408 GKI_freebuf (p_buf); 409 return (L2CAP_DW_FAILED); 410 } 411 412 /* First, see if we already have a link to the remote */ 413 /* then find the channel control block for UCD */ 414 if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL) 415 ||((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL)) 416 { 417 if ( l2c_ucd_connect (rem_bda) == FALSE ) 418 { 419 GKI_freebuf (p_buf); 420 return (L2CAP_DW_FAILED); 421 } 422 423 /* If we still don't have lcb and ccb after connect attempt, then can't proceed */ 424 if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL) 425 || ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL)) 426 { 427 GKI_freebuf (p_buf); 428 return (L2CAP_DW_FAILED); 429 } 430 } 431 432 /* write PSM */ 433 p_buf->offset -= L2CAP_UCD_OVERHEAD; 434 p_buf->len += L2CAP_UCD_OVERHEAD; 435 p = (UINT8 *)(p_buf + 1) + p_buf->offset; 436 437 UINT16_TO_STREAM (p, psm); 438 439 /* UCD MTU check */ 440 if ((p_lcb->ucd_mtu) && (p_buf->len > p_lcb->ucd_mtu)) 441 { 442 L2CAP_TRACE_WARNING ("L2CAP - Handle: 0x%04x UCD bigger than peer's UCD mtu size cannot be sent", p_lcb->handle); 443 GKI_freebuf (p_buf); 444 return (L2CAP_DW_FAILED); 445 } 446 447 /* If already congested, do not accept any more packets */ 448 if (p_ccb->cong_sent) 449 { 450 L2CAP_TRACE_ERROR ("L2CAP - Handle: 0x%04x UCD cannot be sent, already congested count: %u buff_quota: %u", 451 p_lcb->handle, 452 (p_ccb->xmit_hold_q.count + p_lcb->ucd_out_sec_pending_q.count), 453 p_ccb->buff_quota); 454 455 GKI_freebuf (p_buf); 456 return (L2CAP_DW_FAILED); 457 } 458 459 /* channel based, packet based flushable or non-flushable */ 460 p_buf->layer_specific = flags; 461 462 l2c_csm_execute (p_ccb, L2CEVT_L2CA_DATA_WRITE, p_buf); 463 464 if (p_ccb->cong_sent) 465 return (L2CAP_DW_CONGESTED); 466 else 467 return (L2CAP_DW_SUCCESS); 468} 469 470/******************************************************************************* 471** 472** Function L2CA_UcdSetIdleTimeout 473** 474** Description Set UCD Idle timeout. 475** 476** Parameters: BD Addr 477** Timeout in second 478** 479** Return value: TRUE if successs 480** 481*******************************************************************************/ 482BOOLEAN L2CA_UcdSetIdleTimeout ( BD_ADDR rem_bda, UINT16 timeout ) 483{ 484 tL2C_LCB *p_lcb; 485 tL2C_CCB *p_ccb; 486 487 L2CAP_TRACE_API ("L2CA_UcdSetIdleTimeout() Timeout: 0x%04x BDA: %08x%04x", timeout, 488 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], 489 (rem_bda[4]<<8)+rem_bda[5]); 490 491 /* First, see if we already have a link to the remote */ 492 /* then find the channel control block. */ 493 if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL) 494 ||((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL)) 495 { 496 L2CAP_TRACE_WARNING ("L2CAP - no UCD channel"); 497 return (FALSE); 498 } 499 else 500 { 501 p_ccb->fixed_chnl_idle_tout = timeout; 502 return (TRUE); 503 } 504} 505 506/******************************************************************************* 507** 508** Function L2CA_UCDSetTxPriority 509** 510** Description Sets the transmission priority for a connectionless channel. 511** 512** Returns TRUE if a valid channel, else FALSE 513** 514*******************************************************************************/ 515BOOLEAN L2CA_UCDSetTxPriority ( BD_ADDR rem_bda, tL2CAP_CHNL_PRIORITY priority ) 516{ 517 tL2C_LCB *p_lcb; 518 tL2C_CCB *p_ccb; 519 520 L2CAP_TRACE_API ("L2CA_UCDSetTxPriority() priority: 0x%02x BDA: %08x%04x", priority, 521 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], 522 (rem_bda[4]<<8)+rem_bda[5]); 523 524 if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL) 525 { 526 L2CAP_TRACE_WARNING ("L2CAP - no LCB for L2CA_UCDSetTxPriority"); 527 return (FALSE); 528 } 529 530 /* Find the channel control block */ 531 if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL) 532 { 533 L2CAP_TRACE_WARNING ("L2CAP - no CCB for L2CA_UCDSetTxPriority"); 534 return (FALSE); 535 } 536 537 /* it will update the order of CCB in LCB by priority and update round robin service variables */ 538 l2cu_change_pri_ccb (p_ccb, priority); 539 540 return (TRUE); 541} 542 543/******************************************************************************* 544** 545** Function l2c_ucd_connect 546** 547** Description Connect UCD to remote device. 548** 549** Parameters: BD_ADDR of remote device 550** 551** Return value: TRUE if successs 552** 553*******************************************************************************/ 554static BOOLEAN l2c_ucd_connect ( BD_ADDR rem_bda ) 555{ 556 tL2C_LCB *p_lcb; 557 tL2C_CCB *p_ccb; 558 tL2C_RCB *p_rcb; 559 560 L2CAP_TRACE_DEBUG ("l2c_ucd_connect() BDA: %08x%04x", 561 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], 562 (rem_bda[4]<<8)+rem_bda[5]); 563 564 /* Fail if we have not established communications with the controller */ 565 if (!BTM_IsDeviceUp()) 566 { 567 L2CAP_TRACE_WARNING ("l2c_ucd_connect - BTU not ready"); 568 return (FALSE); 569 } 570 571 /* First, see if we already have a link to the remote */ 572 if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL) 573 { 574 /* No link. Get an LCB and start link establishment */ 575 if ( ((p_lcb = l2cu_allocate_lcb (rem_bda, FALSE, BT_TRANSPORT_BR_EDR)) == NULL) 576 || (l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR) == FALSE) ) 577 { 578 L2CAP_TRACE_WARNING ("L2CAP - conn not started l2c_ucd_connect"); 579 return (FALSE); 580 } 581 } 582 else if ( p_lcb->info_rx_bits & (1 << L2CAP_EXTENDED_FEATURES_INFO_TYPE) ) 583 { 584 if (!(p_lcb->peer_ext_fea & L2CAP_EXTFEA_UCD_RECEPTION)) 585 { 586 L2CAP_TRACE_WARNING ("L2CAP - UCD is not supported by peer, l2c_ucd_connect"); 587 return (FALSE); 588 } 589 } 590 591 /* Find the channel control block. */ 592 if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL) 593 { 594 /* Allocate a channel control block */ 595 if ((p_ccb = l2cu_allocate_ccb (p_lcb, 0)) == NULL) 596 { 597 L2CAP_TRACE_WARNING ("L2CAP - no CCB for l2c_ucd_connect"); 598 return (FALSE); 599 } 600 else 601 { 602 /* Set CID for the connection */ 603 p_ccb->local_cid = L2CAP_CONNECTIONLESS_CID; 604 p_ccb->remote_cid = L2CAP_CONNECTIONLESS_CID; 605 606 /* Set the default idle timeout value to use */ 607 p_ccb->fixed_chnl_idle_tout = L2CAP_UCD_IDLE_TIMEOUT; 608 609 /* Set the default channel priority value to use */ 610 l2cu_change_pri_ccb (p_ccb, L2CAP_UCD_CH_PRIORITY); 611 612 if ((p_rcb = l2cu_find_rcb_by_psm (L2C_UCD_RCB_ID)) == NULL) 613 { 614 L2CAP_TRACE_WARNING ("L2CAP - no UCD registered, l2c_ucd_connect"); 615 return (FALSE); 616 } 617 /* Save UCD registration info */ 618 p_ccb->p_rcb = p_rcb; 619 620 /* There is no configuration, so if the link is up, the channel is up */ 621 if (p_lcb->link_state == LST_CONNECTED) 622 { 623 p_ccb->chnl_state = CST_OPEN; 624 } 625 } 626 } 627 628 return (TRUE); 629} 630 631/******************************************************************************* 632** 633** Function l2c_ucd_delete_sec_pending_q 634** 635** Description discard all of UCD packets in security pending queue 636** 637** Returns None 638** 639*******************************************************************************/ 640void l2c_ucd_delete_sec_pending_q(tL2C_LCB *p_lcb) 641{ 642 /* clean up any security pending UCD */ 643 while (p_lcb->ucd_out_sec_pending_q.p_first) 644 GKI_freebuf (GKI_dequeue (&p_lcb->ucd_out_sec_pending_q)); 645 646 while (p_lcb->ucd_in_sec_pending_q.p_first) 647 GKI_freebuf (GKI_dequeue (&p_lcb->ucd_in_sec_pending_q)); 648} 649 650/******************************************************************************* 651** 652** Function l2c_ucd_check_pending_info_req 653** 654** Description check if any application is waiting for UCD information 655** 656** Return TRUE if any pending UCD info request 657** 658*******************************************************************************/ 659BOOLEAN l2c_ucd_check_pending_info_req(tL2C_CCB *p_ccb) 660{ 661 tL2C_RCB *p_rcb = &l2cb.rcb_pool[0]; 662 UINT16 xx; 663 BOOLEAN pending = FALSE; 664 665 if (p_ccb == NULL) 666 { 667 L2CAP_TRACE_ERROR ("L2CAP - NULL p_ccb in l2c_ucd_check_pending_info_req"); 668 return (FALSE); 669 } 670 671 for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) 672 { 673 if (p_rcb->in_use) 674 { 675 /* if application is waiting UCD reception info */ 676 if (p_rcb->ucd.state & L2C_UCD_STATE_W4_RECEPTION) 677 { 678 /* if this information is available */ 679 if ( p_ccb->p_lcb->info_rx_bits & (1 << L2CAP_EXTENDED_FEATURES_INFO_TYPE) ) 680 { 681 if (!(p_ccb->p_lcb->peer_ext_fea & L2CAP_EXTFEA_UCD_RECEPTION)) 682 { 683 L2CAP_TRACE_WARNING ("L2CAP - UCD is not supported by peer, l2c_ucd_check_pending_info_req"); 684 685 l2c_ucd_delete_sec_pending_q(p_ccb->p_lcb); 686 l2cu_release_ccb (p_ccb); 687 } 688 689 p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Discover_Cb (p_ccb->p_lcb->remote_bd_addr, 690 L2CAP_UCD_INFO_TYPE_RECEPTION, 691 p_ccb->p_lcb->peer_ext_fea & L2CAP_EXTFEA_UCD_RECEPTION); 692 } 693 else 694 { 695 pending = TRUE; 696 if (p_ccb->p_lcb->w4_info_rsp == FALSE) 697 { 698 l2cu_send_peer_info_req (p_ccb->p_lcb, L2CAP_EXTENDED_FEATURES_INFO_TYPE); 699 } 700 } 701 } 702 703 /* if application is waiting for UCD MTU */ 704 if (p_rcb->ucd.state & L2C_UCD_STATE_W4_MTU) 705 { 706 /* if this information is available */ 707 if ( p_ccb->p_lcb->info_rx_bits & (1 << L2CAP_CONNLESS_MTU_INFO_TYPE)) 708 { 709 p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Discover_Cb (p_ccb->p_lcb->remote_bd_addr, 710 L2CAP_UCD_INFO_TYPE_MTU, 711 p_ccb->p_lcb->ucd_mtu); 712 } 713 else 714 { 715 pending = TRUE; 716 if (p_ccb->p_lcb->w4_info_rsp == FALSE) 717 { 718 l2cu_send_peer_info_req (p_ccb->p_lcb, L2CAP_CONNLESS_MTU_INFO_TYPE); 719 } 720 } 721 } 722 } 723 } 724 return (pending); 725} 726 727/******************************************************************************* 728** 729** Function l2c_ucd_enqueue_pending_out_sec_q 730** 731** Description enqueue outgoing UCD packet into security pending queue 732** and check congestion 733** 734** Return None 735** 736*******************************************************************************/ 737void l2c_ucd_enqueue_pending_out_sec_q(tL2C_CCB *p_ccb, void *p_data) 738{ 739 GKI_enqueue (&p_ccb->p_lcb->ucd_out_sec_pending_q, p_data); 740 l2cu_check_channel_congestion (p_ccb); 741} 742 743/******************************************************************************* 744** 745** Function l2c_ucd_check_pending_out_sec_q 746** 747** Description check outgoing security 748** 749** Return TRUE if any UCD packet for security 750** 751*******************************************************************************/ 752BOOLEAN l2c_ucd_check_pending_out_sec_q(tL2C_CCB *p_ccb) 753{ 754 UINT8 *p; 755 UINT16 psm; 756 BT_HDR *p_buf; 757 758 if ( p_ccb->p_lcb->ucd_out_sec_pending_q.count ) 759 { 760 p_buf = (BT_HDR*)(p_ccb->p_lcb->ucd_out_sec_pending_q.p_first); 761 p = (UINT8 *)(p_buf + 1) + p_buf->offset; 762 STREAM_TO_UINT16(psm, p) 763 764 p_ccb->chnl_state = CST_ORIG_W4_SEC_COMP; 765 btm_sec_l2cap_access_req (p_ccb->p_lcb->remote_bd_addr, psm, 766 p_ccb->p_lcb->handle, CONNLESS_ORIG, &l2c_link_sec_comp, p_ccb); 767 768 return (TRUE); 769 } 770 return (FALSE); 771} 772 773/******************************************************************************* 774** 775** Function l2c_ucd_send_pending_out_sec_q 776** 777** Description dequeue UCD packet from security pending queue and 778** enqueue it into CCB 779** 780** Return None 781** 782*******************************************************************************/ 783void l2c_ucd_send_pending_out_sec_q(tL2C_CCB *p_ccb) 784{ 785 BT_HDR *p_buf; 786 787 if ( p_ccb->p_lcb->ucd_out_sec_pending_q.count ) 788 { 789 p_buf = (BT_HDR*)GKI_dequeue (&p_ccb->p_lcb->ucd_out_sec_pending_q); 790 791 l2c_enqueue_peer_data (p_ccb, (BT_HDR *)p_buf); 792 l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, NULL); 793 } 794} 795 796/******************************************************************************* 797** 798** Function l2c_ucd_discard_pending_out_sec_q 799** 800** Description dequeue UCD packet from security pending queue and 801** discard it. 802** 803** Return None 804** 805*******************************************************************************/ 806void l2c_ucd_discard_pending_out_sec_q(tL2C_CCB *p_ccb) 807{ 808 BT_HDR *p_buf; 809 810 p_buf = (BT_HDR*)GKI_dequeue (&p_ccb->p_lcb->ucd_out_sec_pending_q); 811 812 /* we may need to report to application */ 813 814 if (p_buf) 815 { 816 GKI_freebuf (p_buf); 817 } 818} 819 820/******************************************************************************* 821** 822** Function l2c_ucd_check_pending_in_sec_q 823** 824** Description check incoming security 825** 826** Return TRUE if any UCD packet for security 827** 828*******************************************************************************/ 829BOOLEAN l2c_ucd_check_pending_in_sec_q(tL2C_CCB *p_ccb) 830{ 831 UINT8 *p; 832 UINT16 psm; 833 BT_HDR *p_buf; 834 835 if ( p_ccb->p_lcb->ucd_in_sec_pending_q.count ) 836 { 837 p_buf = (BT_HDR*)(p_ccb->p_lcb->ucd_in_sec_pending_q.p_first); 838 p = (UINT8 *)(p_buf + 1) + p_buf->offset; 839 STREAM_TO_UINT16(psm, p) 840 841 p_ccb->chnl_state = CST_TERM_W4_SEC_COMP; 842 btm_sec_l2cap_access_req (p_ccb->p_lcb->remote_bd_addr, psm, 843 p_ccb->p_lcb->handle, CONNLESS_TERM, &l2c_link_sec_comp, p_ccb); 844 845 return (TRUE); 846 } 847 return (FALSE); 848} 849 850/******************************************************************************* 851** 852** Function l2c_ucd_send_pending_in_sec_q 853** 854** Description dequeue UCD packet from security pending queue and 855** send it to application 856** 857** Return None 858** 859*******************************************************************************/ 860void l2c_ucd_send_pending_in_sec_q(tL2C_CCB *p_ccb) 861{ 862 BT_HDR *p_buf; 863 864 if ( p_ccb->p_lcb->ucd_in_sec_pending_q.count ) 865 { 866 p_buf = (BT_HDR*)GKI_dequeue (&p_ccb->p_lcb->ucd_in_sec_pending_q); 867 868 p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Data_Cb(p_ccb->p_lcb->remote_bd_addr, (BT_HDR *)p_buf); 869 } 870} 871 872/******************************************************************************* 873** 874** Function l2c_ucd_discard_pending_in_sec_q 875** 876** Description dequeue UCD packet from security pending queue and 877** discard it. 878** 879** Return None 880** 881*******************************************************************************/ 882void l2c_ucd_discard_pending_in_sec_q(tL2C_CCB *p_ccb) 883{ 884 BT_HDR *p_buf; 885 886 p_buf = (BT_HDR*)GKI_dequeue (&p_ccb->p_lcb->ucd_in_sec_pending_q); 887 888 if (p_buf) 889 { 890 GKI_freebuf (p_buf); 891 } 892} 893 894/******************************************************************************* 895** 896** Function l2c_ucd_check_rx_pkts 897** 898** Description Check if UCD reception is registered. 899** Process received UCD packet if application is expecting. 900** 901** Return TRUE if UCD reception is registered 902** 903*******************************************************************************/ 904BOOLEAN l2c_ucd_check_rx_pkts(tL2C_LCB *p_lcb, BT_HDR *p_msg) 905{ 906 tL2C_CCB *p_ccb; 907 tL2C_RCB *p_rcb; 908 909 if (((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) != NULL) 910 ||((p_rcb = l2cu_find_rcb_by_psm (L2C_UCD_RCB_ID)) != NULL)) 911 { 912 if (p_ccb == NULL) 913 { 914 /* Allocate a channel control block */ 915 if ((p_ccb = l2cu_allocate_ccb (p_lcb, 0)) == NULL) 916 { 917 L2CAP_TRACE_WARNING ("L2CAP - no CCB for UCD reception"); 918 GKI_freebuf (p_msg); 919 return TRUE; 920 } 921 else 922 { 923 /* Set CID for the connection */ 924 p_ccb->local_cid = L2CAP_CONNECTIONLESS_CID; 925 p_ccb->remote_cid = L2CAP_CONNECTIONLESS_CID; 926 927 /* Set the default idle timeout value to use */ 928 p_ccb->fixed_chnl_idle_tout = L2CAP_UCD_IDLE_TIMEOUT; 929 930 /* Set the default channel priority value to use */ 931 l2cu_change_pri_ccb (p_ccb, L2CAP_UCD_CH_PRIORITY); 932 933 /* Save registration info */ 934 p_ccb->p_rcb = p_rcb; 935 936 p_ccb->chnl_state = CST_OPEN; 937 } 938 } 939 l2c_csm_execute(p_ccb, L2CEVT_L2CAP_DATA, p_msg); 940 return TRUE; 941 } 942 else 943 return FALSE; 944} 945 946/******************************************************************************* 947** 948** Function l2c_ucd_process_event 949** 950** Description This is called from main state machine when LCID is connectionless 951** Process the event if it is for UCD. 952** 953** Return TRUE if the event is consumed by UCD 954** FALSE if the event needs to be processed by main state machine 955** 956*******************************************************************************/ 957BOOLEAN l2c_ucd_process_event(tL2C_CCB *p_ccb, UINT16 event, void *p_data) 958{ 959 /* if the event is not processed by this function, this variable will be set to FALSE */ 960 BOOLEAN done = TRUE; 961 962 switch (p_ccb->chnl_state) 963 { 964 case CST_CLOSED: 965 switch (event) 966 { 967 case L2CEVT_LP_CONNECT_CFM: /* Link came up */ 968 /* check if waiting for UCD info */ 969 if (!l2c_ucd_check_pending_info_req (p_ccb)) 970 { 971 /* check if any outgoing UCD packet is waiting security check */ 972 if (!l2c_ucd_check_pending_out_sec_q(p_ccb)) 973 { 974 p_ccb->chnl_state = CST_OPEN; 975 } 976 } 977 break; 978 979 case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */ 980 GKI_enqueue (&p_ccb->p_lcb->ucd_in_sec_pending_q, p_data); 981 break; 982 983 case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */ 984 l2c_ucd_enqueue_pending_out_sec_q(p_ccb, p_data); 985 break; 986 987 case L2CEVT_L2CAP_INFO_RSP: 988 /* check if waiting for UCD info */ 989 if (!l2c_ucd_check_pending_info_req (p_ccb)) 990 { 991 /* check if any outgoing UCD packet is waiting security check */ 992 if (!l2c_ucd_check_pending_out_sec_q(p_ccb)) 993 { 994 p_ccb->chnl_state = CST_OPEN; 995 } 996 } 997 break; 998 999 default: 1000 done = FALSE; /* main state machine continues to process event */ 1001 break; 1002 } 1003 break; 1004 1005 case CST_ORIG_W4_SEC_COMP: 1006 switch (event) 1007 { 1008 case L2CEVT_SEC_RE_SEND_CMD: /* BTM has enough info to proceed */ 1009 /* check if any outgoing UCD packet is waiting security check */ 1010 if (!l2c_ucd_check_pending_out_sec_q(p_ccb)) 1011 { 1012 p_ccb->chnl_state = CST_OPEN; 1013 } 1014 break; 1015 1016 case L2CEVT_SEC_COMP: /* Security completed success */ 1017 p_ccb->chnl_state = CST_OPEN; 1018 l2c_ucd_send_pending_out_sec_q(p_ccb); 1019 1020 if ( p_ccb->p_lcb->ucd_out_sec_pending_q.count ) 1021 { 1022 /* start a timer to send next UCD packet in OPEN state */ 1023 /* it will prevent stack overflow */ 1024 btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, 0); 1025 } 1026 else 1027 { 1028 /* start a timer for idle timeout of UCD */ 1029 btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, p_ccb->fixed_chnl_idle_tout); 1030 } 1031 break; 1032 1033 case L2CEVT_SEC_COMP_NEG: 1034 p_ccb->chnl_state = CST_OPEN; 1035 l2c_ucd_discard_pending_out_sec_q(p_ccb); 1036 1037 /* start a timer for idle timeout of UCD */ 1038 btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, p_ccb->fixed_chnl_idle_tout); 1039 break; 1040 1041 case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */ 1042 l2c_ucd_enqueue_pending_out_sec_q(p_ccb, p_data); 1043 break; 1044 1045 case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */ 1046 GKI_enqueue (&p_ccb->p_lcb->ucd_in_sec_pending_q, p_data); 1047 break; 1048 1049 case L2CEVT_L2CAP_INFO_RSP: 1050 /* check if waiting for UCD info */ 1051 l2c_ucd_check_pending_info_req (p_ccb); 1052 break; 1053 1054 default: 1055 done = FALSE; /* main state machine continues to process event */ 1056 break; 1057 } 1058 break; 1059 1060 1061 case CST_TERM_W4_SEC_COMP: 1062 switch (event) 1063 { 1064 case L2CEVT_SEC_COMP: 1065 p_ccb->chnl_state = CST_OPEN; 1066 l2c_ucd_send_pending_in_sec_q (p_ccb); 1067 1068 if ( p_ccb->p_lcb->ucd_in_sec_pending_q.count ) 1069 { 1070 /* start a timer to check next UCD packet in OPEN state */ 1071 /* it will prevent stack overflow */ 1072 btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, 0); 1073 } 1074 else 1075 { 1076 /* start a timer for idle timeout of UCD */ 1077 btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, p_ccb->fixed_chnl_idle_tout); 1078 } 1079 break; 1080 1081 case L2CEVT_SEC_COMP_NEG: 1082 if (((tL2C_CONN_INFO *)p_data)->status == BTM_DELAY_CHECK) 1083 { 1084 done = FALSE; 1085 break; 1086 } 1087 p_ccb->chnl_state = CST_OPEN; 1088 l2c_ucd_discard_pending_in_sec_q (p_ccb); 1089 1090 /* start a timer for idle timeout of UCD */ 1091 btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, p_ccb->fixed_chnl_idle_tout); 1092 break; 1093 1094 case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */ 1095 l2c_ucd_enqueue_pending_out_sec_q(p_ccb, p_data); 1096 break; 1097 1098 case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */ 1099 GKI_enqueue (&p_ccb->p_lcb->ucd_in_sec_pending_q, p_data); 1100 break; 1101 1102 case L2CEVT_SEC_RE_SEND_CMD: /* BTM has enough info to proceed */ 1103 /* check if any incoming UCD packet is waiting security check */ 1104 if (!l2c_ucd_check_pending_in_sec_q(p_ccb)) 1105 { 1106 p_ccb->chnl_state = CST_OPEN; 1107 } 1108 break; 1109 1110 case L2CEVT_L2CAP_INFO_RSP: 1111 /* check if waiting for UCD info */ 1112 l2c_ucd_check_pending_info_req (p_ccb); 1113 break; 1114 1115 default: 1116 done = FALSE; /* main state machine continues to process event */ 1117 break; 1118 } 1119 break; 1120 1121 case CST_OPEN: 1122 switch (event) 1123 { 1124 case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */ 1125 /* stop idle timer of UCD */ 1126 btu_stop_timer (&p_ccb->timer_entry); 1127 1128 GKI_enqueue (&p_ccb->p_lcb->ucd_in_sec_pending_q, p_data); 1129 l2c_ucd_check_pending_in_sec_q (p_ccb); 1130 break; 1131 1132 case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */ 1133 /* stop idle timer of UCD */ 1134 btu_stop_timer (&p_ccb->timer_entry); 1135 1136 l2c_ucd_enqueue_pending_out_sec_q(p_ccb, p_data); 1137 1138 /* coverity[check_return] */ /* coverity[unchecked_value] */ 1139 /* success changes state, failure stays in current state */ 1140 l2c_ucd_check_pending_out_sec_q (p_ccb); 1141 break; 1142 1143 case L2CEVT_TIMEOUT: 1144 /* check if any UCD packet is waiting security check */ 1145 if ((!l2c_ucd_check_pending_in_sec_q(p_ccb)) 1146 &&(!l2c_ucd_check_pending_out_sec_q(p_ccb))) 1147 { 1148 l2cu_release_ccb (p_ccb); 1149 } 1150 break; 1151 1152 case L2CEVT_L2CAP_INFO_RSP: 1153 /* check if waiting for UCD info */ 1154 l2c_ucd_check_pending_info_req (p_ccb); 1155 break; 1156 1157 default: 1158 done = FALSE; /* main state machine continues to process event */ 1159 break; 1160 } 1161 break; 1162 1163 default: 1164 done = FALSE; /* main state machine continues to process event */ 1165 break; 1166 } 1167 1168 return done; 1169} 1170#endif /* (L2CAP_UCD_INCLUDED == TRUE) */ 1171