rfc_ts_frames.c revision e448862a47c08eb23185aaed574b39264f5005fc
1/***************************************************************************** 2** 3** Name: rfc_ts_frames.c 4** 5** Description: This file contains functions to send TS 07.10 frames 6** 7** 8** Copyright (c) 1999-2008, Broadcom Corp., All Rights Reserved. 9** WIDCOMM Bluetooth Core. Proprietary and confidential. 10******************************************************************************/ 11#include "bt_target.h" 12#include "gki.h" 13#include "rfcdefs.h" 14#include "port_api.h" 15#include "l2c_api.h" 16#include "port_int.h" 17#include "rfc_int.h" 18 19/******************************************************************************* 20** 21** Function rfc_send_sabme 22** 23** Description This function sends SABME frame. 24** 25*******************************************************************************/ 26void rfc_send_sabme (tRFC_MCB *p_mcb, UINT8 dlci) 27{ 28 BT_HDR *p_buf; 29 UINT8 *p_data; 30 UINT8 cr = RFCOMM_CR(p_mcb->is_initiator, TRUE); 31 32 if ((p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_CMD_POOL_ID)) == NULL) 33 return; 34 35 p_buf->offset = L2CAP_MIN_OFFSET; 36 p_data = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET; 37 38 /* SABME frame, command, PF = 1, dlci */ 39 *p_data++ = RFCOMM_EA | cr | (dlci << RFCOMM_SHIFT_DLCI); 40 *p_data++ = RFCOMM_SABME | RFCOMM_PF; 41 *p_data++ = RFCOMM_EA | 0; 42 43 *p_data = RFCOMM_SABME_FCS ((UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET, cr, dlci); 44 45 p_buf->len = 4; 46 47 rfc_check_send_cmd(p_mcb, p_buf); 48} 49 50 51/******************************************************************************* 52** 53** Function rfc_send_ua 54** 55** Description This function sends UA frame. 56** 57*******************************************************************************/ 58void rfc_send_ua (tRFC_MCB *p_mcb, UINT8 dlci) 59{ 60 BT_HDR *p_buf; 61 UINT8 *p_data; 62 UINT8 cr = RFCOMM_CR(p_mcb->is_initiator, FALSE); 63 64 if ((p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_CMD_POOL_ID)) == NULL) 65 return; 66 67 p_buf->offset = L2CAP_MIN_OFFSET; 68 p_data = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET; 69 70 /* ua frame, response, PF = 1, dlci */ 71 *p_data++ = RFCOMM_EA | cr | (dlci << RFCOMM_SHIFT_DLCI); 72 *p_data++ = RFCOMM_UA | RFCOMM_PF; 73 *p_data++ = RFCOMM_EA | 0; 74 75 *p_data = RFCOMM_UA_FCS ((UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET, cr, dlci); 76 77 p_buf->len = 4; 78 79 rfc_check_send_cmd(p_mcb, p_buf); 80} 81 82 83/******************************************************************************* 84** 85** Function rfc_send_dm 86** 87** Description This function sends DM frame. 88** 89*******************************************************************************/ 90void rfc_send_dm (tRFC_MCB *p_mcb, UINT8 dlci, BOOLEAN pf) 91{ 92 BT_HDR *p_buf; 93 UINT8 *p_data; 94 UINT8 cr = RFCOMM_CR(p_mcb->is_initiator, FALSE); 95 96 if ((p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_CMD_POOL_ID)) == NULL) 97 return; 98 99 p_buf->offset = L2CAP_MIN_OFFSET; 100 p_data = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET; 101 102 /* DM frame, response, PF = 1, dlci */ 103 *p_data++ = RFCOMM_EA | cr | (dlci << RFCOMM_SHIFT_DLCI); 104 *p_data++ = RFCOMM_DM | ((pf) ? RFCOMM_PF : 0); 105 *p_data++ = RFCOMM_EA | 0; 106 107 *p_data = RFCOMM_DM_FCS ((UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET, cr, dlci); 108 109 p_buf->len = 4; 110 111 rfc_check_send_cmd(p_mcb, p_buf); 112} 113 114 115/******************************************************************************* 116** 117** Function rfc_send_disc 118** 119** Description This function sends DISC frame. 120** 121*******************************************************************************/ 122void rfc_send_disc (tRFC_MCB *p_mcb, UINT8 dlci) 123{ 124 BT_HDR *p_buf; 125 UINT8 *p_data; 126 UINT8 cr = RFCOMM_CR(p_mcb->is_initiator, TRUE); 127 128 if ((p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_CMD_POOL_ID)) == NULL) 129 return; 130 131 p_buf->offset = L2CAP_MIN_OFFSET; 132 p_data = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET; 133 134 /* DISC frame, command, PF = 1, dlci */ 135 *p_data++ = RFCOMM_EA | cr | (dlci << RFCOMM_SHIFT_DLCI); 136 *p_data++ = RFCOMM_DISC | RFCOMM_PF; 137 *p_data++ = RFCOMM_EA | 0; 138 139 *p_data = RFCOMM_DISC_FCS ((UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET, cr, dlci); 140 141 p_buf->len = 4; 142 143 rfc_check_send_cmd(p_mcb, p_buf); 144} 145 146 147/******************************************************************************* 148** 149** Function rfc_send_buf_uih 150** 151** Description This function sends UIH frame. 152** 153*******************************************************************************/ 154void rfc_send_buf_uih (tRFC_MCB *p_mcb, UINT8 dlci, BT_HDR *p_buf) 155{ 156 UINT8 *p_data; 157 UINT8 cr = RFCOMM_CR(p_mcb->is_initiator, TRUE); 158 UINT8 credits; 159 160 p_buf->offset -= RFCOMM_CTRL_FRAME_LEN; 161 if (p_buf->len > 127) 162 p_buf->offset--; 163 164 if (dlci) 165 credits = (UINT8)p_buf->layer_specific; 166 else 167 credits = 0; 168 169 if (credits) 170 p_buf->offset--; 171 172 p_data = (UINT8 *)(p_buf + 1) + p_buf->offset; 173 174 /* UIH frame, command, PF = 0, dlci */ 175 *p_data++ = RFCOMM_EA | cr | (dlci << RFCOMM_SHIFT_DLCI); 176 *p_data++ = RFCOMM_UIH | ((credits) ? RFCOMM_PF : 0); 177 if (p_buf->len <= 127) 178 { 179 *p_data++ = RFCOMM_EA | (p_buf->len << 1); 180 p_buf->len += 3; 181 } 182 else 183 { 184 *p_data++ = (p_buf->len & 0x7f) << 1; 185 *p_data++ = p_buf->len >> RFCOMM_SHIFT_LENGTH2; 186 p_buf->len += 4; 187 } 188 189 if (credits) 190 { 191 *p_data++ = credits; 192 p_buf->len++; 193 } 194 195 p_data = (UINT8 *)(p_buf + 1) + p_buf->offset + p_buf->len++; 196 197 *p_data = RFCOMM_UIH_FCS ((UINT8 *)(p_buf + 1) + p_buf->offset, dlci); 198 199 if (dlci == RFCOMM_MX_DLCI) 200 { 201 rfc_check_send_cmd(p_mcb, p_buf); 202 } 203 else 204 { 205 206 L2CA_DataWrite (p_mcb->lcid, p_buf); 207 } 208} 209 210 211/******************************************************************************* 212** 213** Function rfc_send_pn 214** 215** Description This function sends DLC Parameters Negotiation Frame. 216** 217*******************************************************************************/ 218void rfc_send_pn (tRFC_MCB *p_mcb, UINT8 dlci, BOOLEAN is_command, UINT16 mtu, UINT8 cl, UINT8 k) 219{ 220 BT_HDR *p_buf; 221 UINT8 *p_data; 222 223 if ((p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_CMD_POOL_ID)) == NULL) 224 return; 225 226 p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN; 227 p_data = (UINT8 *)(p_buf + 1) + p_buf->offset; 228 229 *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_PN; 230 *p_data++ = RFCOMM_EA | (RFCOMM_MX_PN_LEN << 1); 231 232 *p_data++ = dlci; 233 *p_data++ = RFCOMM_PN_FRAM_TYPE_UIH | cl; 234 235 /* It appeared that we need to reply with the same priority bits as we received. 236 ** We will use the fact that we reply in the same context so rx_frame can still be used. 237 */ 238 if (is_command) 239 *p_data++ = RFCOMM_PN_PRIORITY_0; 240 else 241 *p_data++ = rfc_cb.rfc.rx_frame.u.pn.priority; 242 243 *p_data++ = RFCOMM_T1_DSEC; 244 *p_data++ = mtu & 0xFF; 245 *p_data++ = mtu >> 8; 246 *p_data++ = RFCOMM_N2; 247 *p_data = k; 248 249 /* Total length is sizeof PN data + mx header 2 */ 250 p_buf->len = RFCOMM_MX_PN_LEN + 2; 251 252 rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf); 253} 254 255 256/******************************************************************************* 257** 258** Function rfc_send_fcon 259** 260** Description This function sends Flow Control On Command. 261** 262*******************************************************************************/ 263void rfc_send_fcon (tRFC_MCB *p_mcb, BOOLEAN is_command) 264{ 265 BT_HDR *p_buf; 266 UINT8 *p_data; 267 268 if ((p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_CMD_POOL_ID)) == NULL) 269 return; 270 271 p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN; 272 p_data = (UINT8 *)(p_buf + 1) + p_buf->offset; 273 274 *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_FCON; 275 *p_data++ = RFCOMM_EA | (RFCOMM_MX_FCON_LEN << 1); 276 277 /* Total length is sizeof FCON data + mx header 2 */ 278 p_buf->len = RFCOMM_MX_FCON_LEN + 2; 279 280 rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf); 281} 282 283 284/******************************************************************************* 285** 286** Function rfc_send_fcoff 287** 288** Description This function sends Flow Control Off Command. 289** 290*******************************************************************************/ 291void rfc_send_fcoff (tRFC_MCB *p_mcb, BOOLEAN is_command) 292{ 293 BT_HDR *p_buf; 294 UINT8 *p_data; 295 296 if ((p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_CMD_POOL_ID)) == NULL) 297 return; 298 299 p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN; 300 p_data = (UINT8 *)(p_buf + 1) + p_buf->offset; 301 302 *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_FCOFF; 303 *p_data++ = RFCOMM_EA | (RFCOMM_MX_FCOFF_LEN << 1); 304 305 /* Total length is sizeof FCOFF data + mx header 2 */ 306 p_buf->len = RFCOMM_MX_FCOFF_LEN + 2; 307 308 rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf); 309} 310 311 312/******************************************************************************* 313** 314** Function rfc_send_msc 315** 316** Description This function sends Modem Status Command Frame. 317** 318*******************************************************************************/ 319void rfc_send_msc (tRFC_MCB *p_mcb, UINT8 dlci, BOOLEAN is_command, 320 tPORT_CTRL *p_pars) 321{ 322 BT_HDR *p_buf; 323 UINT8 *p_data; 324 UINT8 signals; 325 UINT8 break_duration; 326 UINT8 len; 327 328 signals = p_pars->modem_signal; 329 break_duration = p_pars->break_signal; 330 331 if ((p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_CMD_POOL_ID)) == NULL) 332 return; 333 334 p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN; 335 p_data = (UINT8 *)(p_buf + 1) + p_buf->offset; 336 337 if (break_duration) 338 len = RFCOMM_MX_MSC_LEN_WITH_BREAK; 339 else 340 len = RFCOMM_MX_MSC_LEN_NO_BREAK; 341 342 *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_MSC; 343 *p_data++ = RFCOMM_EA | (len << 1); 344 345 *p_data++ = RFCOMM_EA | RFCOMM_CR_MASK | (dlci << RFCOMM_SHIFT_DLCI); 346 *p_data++ = RFCOMM_EA | 347 ((p_pars->fc) ? RFCOMM_MSC_FC : 0) | 348 ((signals & MODEM_SIGNAL_DTRDSR) ? RFCOMM_MSC_RTC : 0) | 349 ((signals & MODEM_SIGNAL_RTSCTS) ? RFCOMM_MSC_RTR : 0) | 350 ((signals & MODEM_SIGNAL_RI) ? RFCOMM_MSC_IC : 0) | 351 ((signals & MODEM_SIGNAL_DCD) ? RFCOMM_MSC_DV : 0); 352 353 if (break_duration) 354 { 355 *p_data++ = RFCOMM_EA | RFCOMM_MSC_BREAK_PRESENT_MASK | 356 (break_duration << RFCOMM_MSC_SHIFT_BREAK); 357 } 358 359 /* Total length is sizeof MSC data + mx header 2 */ 360 p_buf->len = len + 2; 361 362 rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf); 363} 364 365 366/******************************************************************************* 367** 368** Function rfc_send_rls 369** 370** Description This function sends Remote Line Status Command Frame. 371** 372*******************************************************************************/ 373void rfc_send_rls (tRFC_MCB *p_mcb, UINT8 dlci, BOOLEAN is_command, UINT8 status) 374{ 375 BT_HDR *p_buf; 376 UINT8 *p_data; 377 378 if ((p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_CMD_POOL_ID)) == NULL) 379 return; 380 381 p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN; 382 p_data = (UINT8 *)(p_buf + 1) + p_buf->offset; 383 384 *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_RLS; 385 *p_data++ = RFCOMM_EA | (RFCOMM_MX_RLS_LEN << 1); 386 387 *p_data++ = RFCOMM_EA | RFCOMM_CR_MASK | (dlci << RFCOMM_SHIFT_DLCI); 388 *p_data++ = RFCOMM_RLS_ERROR | status; 389 390 /* Total length is sizeof RLS data + mx header 2 */ 391 p_buf->len = RFCOMM_MX_RLS_LEN + 2; 392 393 rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf); 394} 395 396 397/******************************************************************************* 398** 399** Function rfc_send_nsc 400** 401** Description This function sends Non Supported Command Response. 402** 403*******************************************************************************/ 404void rfc_send_nsc (tRFC_MCB *p_mcb) 405{ 406 BT_HDR *p_buf; 407 UINT8 *p_data; 408 409 if ((p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_CMD_POOL_ID)) == NULL) 410 return; 411 412 p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN; 413 p_data = (UINT8 *)(p_buf + 1) + p_buf->offset; 414 415 *p_data++ = RFCOMM_EA | RFCOMM_I_CR(FALSE) | RFCOMM_MX_NSC; 416 *p_data++ = RFCOMM_EA | (RFCOMM_MX_NSC_LEN << 1); 417 418 *p_data++ = rfc_cb.rfc.rx_frame.ea | 419 (rfc_cb.rfc.rx_frame.cr << RFCOMM_SHIFT_CR) | 420 rfc_cb.rfc.rx_frame.type; 421 422 /* Total length is sizeof NSC data + mx header 2 */ 423 p_buf->len = RFCOMM_MX_NSC_LEN + 2; 424 425 rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf); 426} 427 428 429/******************************************************************************* 430** 431** Function rfc_send_rpn 432** 433** Description This function sends Remote Port Negotiation Command 434** 435*******************************************************************************/ 436void rfc_send_rpn (tRFC_MCB *p_mcb, UINT8 dlci, BOOLEAN is_command, 437 tPORT_STATE *p_pars, UINT16 mask) 438{ 439 BT_HDR *p_buf; 440 UINT8 *p_data; 441 442 if ((p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_CMD_POOL_ID)) == NULL) 443 return; 444 445 p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN; 446 p_data = (UINT8 *)(p_buf + 1) + p_buf->offset; 447 448 *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_RPN; 449 450 if (!p_pars) 451 { 452 *p_data++ = RFCOMM_EA | (RFCOMM_MX_RPN_REQ_LEN << 1); 453 454 *p_data++ = RFCOMM_EA | RFCOMM_CR_MASK | (dlci << RFCOMM_SHIFT_DLCI); 455 456 p_buf->len = RFCOMM_MX_RPN_REQ_LEN + 2; 457 } 458 else 459 { 460 *p_data++ = RFCOMM_EA | (RFCOMM_MX_RPN_LEN << 1); 461 462 *p_data++ = RFCOMM_EA | RFCOMM_CR_MASK | (dlci << RFCOMM_SHIFT_DLCI); 463 *p_data++ = p_pars->baud_rate; 464 *p_data++ = (p_pars->byte_size << RFCOMM_RPN_BITS_SHIFT) 465 | (p_pars->stop_bits << RFCOMM_RPN_STOP_BITS_SHIFT) 466 | (p_pars->parity << RFCOMM_RPN_PARITY_SHIFT) 467 | (p_pars->parity_type << RFCOMM_RPN_PARITY_TYPE_SHIFT); 468 *p_data++ = p_pars->fc_type; 469 *p_data++ = p_pars->xon_char; 470 *p_data++ = p_pars->xoff_char; 471 *p_data++ = (mask & 0xFF); 472 *p_data++ = (mask >> 8); 473 474 /* Total length is sizeof RPN data + mx header 2 */ 475 p_buf->len = RFCOMM_MX_RPN_LEN + 2; 476 } 477 478 rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf); 479} 480 481 482/******************************************************************************* 483** 484** Function rfc_send_test 485** 486** Description This function sends Test frame. 487** 488*******************************************************************************/ 489void rfc_send_test (tRFC_MCB *p_mcb, BOOLEAN is_command, BT_HDR *p_buf) 490{ 491 UINT8 *p_data; 492 UINT16 xx; 493 UINT8 *p_src, *p_dest; 494 495 /* Shift buffer to give space for header */ 496 if (p_buf->offset < (L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET + 2)) 497 { 498 p_src = (UINT8 *) (p_buf + 1) + p_buf->offset + p_buf->len - 1; 499 p_dest = (UINT8 *) (p_buf + 1) + L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET + 2 + p_buf->len - 1; 500 501 for (xx = 0; xx < p_buf->len; xx++) 502 *p_dest-- = *p_src--; 503 504 p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET + 2; 505 } 506 507 /* Adjust offset by number of bytes we are going to fill */ 508 p_buf->offset -= 2; 509 p_data = (UINT8 *)(p_buf + 1) + p_buf->offset; 510 511 *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_TEST; 512 *p_data++ = RFCOMM_EA | (p_buf->len << 1); 513 514 p_buf->len += 2; 515 516 rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf); 517} 518 519/******************************************************************************* 520** 521** Function rfc_send_credit 522** 523** Description This function sends a flow control credit in UIH frame. 524** 525*******************************************************************************/ 526void rfc_send_credit(tRFC_MCB *p_mcb, UINT8 dlci, UINT8 credit) 527{ 528 BT_HDR *p_buf; 529 UINT8 *p_data; 530 UINT8 cr = RFCOMM_CR(p_mcb->is_initiator, TRUE); 531 532 if ((p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_CMD_POOL_ID)) == NULL) 533 return; 534 535 p_buf->offset = L2CAP_MIN_OFFSET; 536 p_data = (UINT8 *)(p_buf + 1) + p_buf->offset; 537 538 *p_data++ = RFCOMM_EA | cr | (dlci << RFCOMM_SHIFT_DLCI); 539 *p_data++ = RFCOMM_UIH | RFCOMM_PF; 540 *p_data++ = RFCOMM_EA | 0; 541 *p_data++ = credit; 542 *p_data = RFCOMM_UIH_FCS ((UINT8 *)(p_buf + 1) + p_buf->offset, dlci); 543 544 p_buf->len = 5; 545 546 rfc_check_send_cmd(p_mcb, p_buf); 547} 548 549 550/******************************************************************************* 551** 552** Function rfc_parse_data 553** 554** Description This function processes data packet received from L2CAP 555** 556*******************************************************************************/ 557UINT8 rfc_parse_data (tRFC_MCB *p_mcb, MX_FRAME *p_frame, BT_HDR *p_buf) 558{ 559 UINT8 ead, eal, fcs; 560 UINT8 *p_data = (UINT8 *)(p_buf + 1) + p_buf->offset; 561 UINT8 *p_start = p_data; 562 UINT16 len; 563 564 if (p_buf->len < RFCOMM_CTRL_FRAME_LEN) 565 { 566 RFCOMM_TRACE_ERROR1 ("Bad Length1: %d", p_buf->len); 567 return (RFC_EVENT_BAD_FRAME); 568 } 569 570 RFCOMM_PARSE_CTRL_FIELD (ead, p_frame->cr, p_frame->dlci, p_data); 571 if( !ead ) 572 { 573 RFCOMM_TRACE_ERROR0 ("Bad Address(EA must be 1)"); 574 return (RFC_EVENT_BAD_FRAME); 575 } 576 RFCOMM_PARSE_TYPE_FIELD (p_frame->type, p_frame->pf, p_data); 577 RFCOMM_PARSE_LEN_FIELD (eal, len, p_data); 578 579 p_buf->len -= (3 + !ead + !eal + 1); /* Additional 1 for FCS */ 580 p_buf->offset += (3 + !ead + !eal); 581 582 /* handle credit if credit based flow control */ 583 if ((p_mcb->flow == PORT_FC_CREDIT) && (p_frame->type == RFCOMM_UIH) && 584 (p_frame->dlci != RFCOMM_MX_DLCI) && (p_frame->pf == 1)) 585 { 586 p_frame->credit = *p_data++; 587 p_buf->len--; 588 p_buf->offset++; 589 } 590 else 591 p_frame->credit = 0; 592 593 if (p_buf->len != len) 594 { 595 RFCOMM_TRACE_ERROR2 ("Bad Length2 %d %d", p_buf->len, len); 596 return (RFC_EVENT_BAD_FRAME); 597 } 598 599 fcs = *(p_data + len); 600 601 /* All control frames that we are sending are sent with P=1, expect */ 602 /* reply with F=1 */ 603 /* According to TS 07.10 spec ivalid frames are discarded without */ 604 /* notification to the sender */ 605 switch (p_frame->type) 606 { 607 case RFCOMM_SABME: 608 if (RFCOMM_FRAME_IS_RSP(p_mcb->is_initiator, p_frame->cr) 609 || !p_frame->pf || len || !RFCOMM_VALID_DLCI (p_frame->dlci) 610 || !rfc_check_fcs (RFCOMM_CTRL_FRAME_LEN, p_start, fcs)) 611 { 612 RFCOMM_TRACE_ERROR0 ("Bad SABME"); 613 return (RFC_EVENT_BAD_FRAME); 614 } 615 else 616 return (RFC_EVENT_SABME); 617 618 case RFCOMM_UA: 619 if (RFCOMM_FRAME_IS_CMD(p_mcb->is_initiator, p_frame->cr) 620 || !p_frame->pf || len || !RFCOMM_VALID_DLCI (p_frame->dlci) 621 || !rfc_check_fcs (RFCOMM_CTRL_FRAME_LEN, p_start, fcs)) 622 { 623 RFCOMM_TRACE_ERROR0 ("Bad UA"); 624 return (RFC_EVENT_BAD_FRAME); 625 } 626 else 627 return (RFC_EVENT_UA); 628 629 case RFCOMM_DM: 630 if (RFCOMM_FRAME_IS_CMD(p_mcb->is_initiator, p_frame->cr) 631 || len || !RFCOMM_VALID_DLCI(p_frame->dlci) 632 || !rfc_check_fcs (RFCOMM_CTRL_FRAME_LEN, p_start, fcs)) 633 { 634 RFCOMM_TRACE_ERROR0 ("Bad DM"); 635 return (RFC_EVENT_BAD_FRAME); 636 } 637 else 638 return (RFC_EVENT_DM); 639 640 case RFCOMM_DISC: 641 if (RFCOMM_FRAME_IS_RSP(p_mcb->is_initiator, p_frame->cr) 642 || !p_frame->pf || len || !RFCOMM_VALID_DLCI(p_frame->dlci) 643 || !rfc_check_fcs (RFCOMM_CTRL_FRAME_LEN, p_start, fcs)) 644 { 645 RFCOMM_TRACE_ERROR0 ("Bad DISC"); 646 return (RFC_EVENT_BAD_FRAME); 647 } 648 else 649 return (RFC_EVENT_DISC); 650 651 case RFCOMM_UIH: 652 if (!RFCOMM_VALID_DLCI(p_frame->dlci)) 653 { 654 RFCOMM_TRACE_ERROR0 ("Bad UIH - invalid DLCI"); 655 return (RFC_EVENT_BAD_FRAME); 656 } 657 else if (!rfc_check_fcs (2, p_start, fcs)) 658 { 659 RFCOMM_TRACE_ERROR0 ("Bad UIH - FCS"); 660 return (RFC_EVENT_BAD_FRAME); 661 } 662 else if (RFCOMM_FRAME_IS_RSP(p_mcb->is_initiator, p_frame->cr)) 663 { 664 /* we assume that this is ok to allow bad implementations to work */ 665 RFCOMM_TRACE_ERROR0 ("Bad UIH - response"); 666 return (RFC_EVENT_UIH); 667 } 668 else 669 return (RFC_EVENT_UIH); 670 } 671 672 return (RFC_EVENT_BAD_FRAME); 673} 674 675 676/******************************************************************************* 677** 678** Function rfc_process_mx_message 679** 680** Description This function processes UIH frames received on the 681** multiplexer control channel. 682** 683*******************************************************************************/ 684void rfc_process_mx_message (tRFC_MCB *p_mcb, BT_HDR *p_buf) 685{ 686 UINT8 *p_data = (UINT8 *)(p_buf + 1) + p_buf->offset; 687 MX_FRAME *p_rx_frame = &rfc_cb.rfc.rx_frame; 688 UINT16 length = p_buf->len; 689 UINT8 ea, cr, mx_len; 690 BOOLEAN is_command; 691 692 p_rx_frame->ea = *p_data & RFCOMM_EA; 693 p_rx_frame->cr = (*p_data & RFCOMM_CR_MASK) >> RFCOMM_SHIFT_CR; 694 p_rx_frame->type = *p_data++ & ~(RFCOMM_CR_MASK | RFCOMM_EA_MASK); 695 696 if (!p_rx_frame->ea || !length) 697 { 698 RFCOMM_TRACE_ERROR2 ("Illegal MX Frame ea:%d len:%d", p_rx_frame->ea, length); 699 GKI_freebuf (p_buf); 700 return; 701 } 702 703 length--; 704 705 is_command = p_rx_frame->cr; 706 707 ea = *p_data & RFCOMM_EA; 708 709 mx_len = *p_data++ >> RFCOMM_SHIFT_LENGTH1; 710 length--; 711 712 if (!ea) 713 { 714 mx_len += *p_data++ << RFCOMM_SHIFT_LENGTH2; 715 length --; 716 } 717 718 if (mx_len != length) 719 { 720 RFCOMM_TRACE_ERROR0 ("Bad MX frame"); 721 GKI_freebuf (p_buf); 722 return; 723 } 724 725 switch (p_rx_frame->type) 726 { 727 case RFCOMM_MX_PN: 728 if (length != RFCOMM_MX_PN_LEN) 729 break; 730 731 p_rx_frame->dlci = *p_data++ & RFCOMM_PN_DLCI_MASK; 732 p_rx_frame->u.pn.frame_type = *p_data & RFCOMM_PN_FRAME_TYPE_MASK; 733 p_rx_frame->u.pn.conv_layer = *p_data++ & RFCOMM_PN_CONV_LAYER_MASK; 734 p_rx_frame->u.pn.priority = *p_data++ & RFCOMM_PN_PRIORITY_MASK; 735 p_rx_frame->u.pn.t1 = *p_data++; 736 p_rx_frame->u.pn.mtu = *p_data + (*(p_data + 1) << 8); 737 p_data += 2; 738 p_rx_frame->u.pn.n2 = *p_data++; 739 p_rx_frame->u.pn.k = *p_data++ & RFCOMM_PN_K_MASK; 740 741 if (!p_rx_frame->dlci 742 || !RFCOMM_VALID_DLCI (p_rx_frame->dlci) 743 || (p_rx_frame->u.pn.mtu < RFCOMM_MIN_MTU) 744 || (p_rx_frame->u.pn.mtu > RFCOMM_MAX_MTU)) 745 { 746 RFCOMM_TRACE_ERROR0 ("Bad PN frame"); 747 break; 748 } 749 750 GKI_freebuf (p_buf); 751 752 rfc_process_pn (p_mcb, is_command, p_rx_frame); 753 return; 754 755 case RFCOMM_MX_TEST: 756 if (!length) 757 break; 758 759 p_rx_frame->u.test.p_data = p_data; 760 p_rx_frame->u.test.data_len = length; 761 762 p_buf->offset += 2; 763 p_buf->len -= 2; 764 765 if (is_command) 766 rfc_send_test (p_mcb, FALSE, p_buf); 767 else 768 rfc_process_test_rsp (p_mcb, p_buf); 769 return; 770 771 case RFCOMM_MX_FCON: 772 if (length != RFCOMM_MX_FCON_LEN) 773 break; 774 775 GKI_freebuf (p_buf); 776 777 rfc_process_fcon (p_mcb, is_command); 778 return; 779 780 case RFCOMM_MX_FCOFF: 781 if (length != RFCOMM_MX_FCOFF_LEN) 782 break; 783 784 GKI_freebuf (p_buf); 785 786 rfc_process_fcoff (p_mcb, is_command); 787 return; 788 789 case RFCOMM_MX_MSC: 790 791 ea = *p_data & RFCOMM_EA; 792 cr = (*p_data & RFCOMM_CR_MASK) >> RFCOMM_SHIFT_CR; 793 p_rx_frame->dlci = *p_data++ >> RFCOMM_SHIFT_DLCI; 794 795 if (!ea || !cr || !p_rx_frame->dlci 796 || !RFCOMM_VALID_DLCI (p_rx_frame->dlci)) 797 { 798 RFCOMM_TRACE_ERROR0 ("Bad MSC frame"); 799 break; 800 } 801 802 p_rx_frame->u.msc.signals = *p_data++; 803 804 if (mx_len == RFCOMM_MX_MSC_LEN_WITH_BREAK) 805 { 806 p_rx_frame->u.msc.break_present = *p_data & RFCOMM_MSC_BREAK_PRESENT_MASK; 807 p_rx_frame->u.msc.break_duration = (*p_data & RFCOMM_MSC_BREAK_MASK) >> RFCOMM_MSC_SHIFT_BREAK; 808 } 809 else 810 { 811 p_rx_frame->u.msc.break_present = FALSE; 812 p_rx_frame->u.msc.break_duration = 0; 813 } 814 GKI_freebuf (p_buf); 815 816 rfc_process_msc (p_mcb, is_command, p_rx_frame); 817 return; 818 819 case RFCOMM_MX_NSC: 820 if ((length != RFCOMM_MX_NSC_LEN) || !is_command) 821 break; 822 823 p_rx_frame->u.nsc.ea = *p_data & RFCOMM_EA; 824 p_rx_frame->u.nsc.cr = (*p_data & RFCOMM_CR_MASK) >> RFCOMM_SHIFT_CR; 825 p_rx_frame->u.nsc.type = *p_data++ >> RFCOMM_SHIFT_DLCI; 826 827 GKI_freebuf (p_buf); 828 829 rfc_process_nsc (p_mcb, p_rx_frame); 830 return; 831 832 case RFCOMM_MX_RPN: 833 if ((length != RFCOMM_MX_RPN_REQ_LEN) && (length != RFCOMM_MX_RPN_LEN)) 834 break; 835 836 ea = *p_data & RFCOMM_EA; 837 cr = (*p_data & RFCOMM_CR_MASK) >> RFCOMM_SHIFT_CR; 838 p_rx_frame->dlci = *p_data++ >> RFCOMM_SHIFT_DLCI; 839 840 if (!ea || !cr || !p_rx_frame->dlci 841 || !RFCOMM_VALID_DLCI (p_rx_frame->dlci)) 842 { 843 RFCOMM_TRACE_ERROR0 ("Bad RPN frame"); 844 break; 845 } 846 847 p_rx_frame->u.rpn.is_request = (length == RFCOMM_MX_RPN_REQ_LEN); 848 849 if (!p_rx_frame->u.rpn.is_request) 850 { 851 p_rx_frame->u.rpn.baud_rate = *p_data++; 852 p_rx_frame->u.rpn.byte_size = (*p_data >> RFCOMM_RPN_BITS_SHIFT) & RFCOMM_RPN_BITS_MASK; 853 p_rx_frame->u.rpn.stop_bits = (*p_data >> RFCOMM_RPN_STOP_BITS_SHIFT) & RFCOMM_RPN_STOP_BITS_MASK; 854 p_rx_frame->u.rpn.parity = (*p_data >> RFCOMM_RPN_PARITY_SHIFT) & RFCOMM_RPN_PARITY_MASK; 855 p_rx_frame->u.rpn.parity_type = (*p_data++ >> RFCOMM_RPN_PARITY_TYPE_SHIFT) & RFCOMM_RPN_PARITY_TYPE_MASK; 856 857 p_rx_frame->u.rpn.fc_type = *p_data++ & RFCOMM_FC_MASK; 858 p_rx_frame->u.rpn.xon_char = *p_data++; 859 p_rx_frame->u.rpn.xoff_char = *p_data++; 860 p_rx_frame->u.rpn.param_mask = (*p_data + (*(p_data + 1) << 8)) & RFCOMM_RPN_PM_MASK; 861 } 862 GKI_freebuf (p_buf); 863 864 rfc_process_rpn (p_mcb, is_command, p_rx_frame->u.rpn.is_request, p_rx_frame); 865 return; 866 867 case RFCOMM_MX_RLS: 868 if (length != RFCOMM_MX_RLS_LEN) 869 break; 870 871 ea = *p_data & RFCOMM_EA; 872 cr = (*p_data & RFCOMM_CR_MASK) >> RFCOMM_SHIFT_CR; 873 874 p_rx_frame->dlci = *p_data++ >> RFCOMM_SHIFT_DLCI; 875 p_rx_frame->u.rls.line_status = (*p_data & ~0x01); 876 877 if (!ea || !cr || !p_rx_frame->dlci 878 || !RFCOMM_VALID_DLCI (p_rx_frame->dlci)) 879 { 880 RFCOMM_TRACE_ERROR0 ("Bad RPN frame"); 881 break; 882 } 883 884 GKI_freebuf (p_buf); 885 886 rfc_process_rls (p_mcb, is_command, p_rx_frame); 887 return; 888 } 889 890 GKI_freebuf (p_buf); 891 892 if (is_command) 893 rfc_send_nsc (p_mcb); 894} 895 896