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