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