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