• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 *******************************************************************************/
rfc_send_sabme(tRFC_MCB * p_mcb,UINT8 dlci)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 *******************************************************************************/
rfc_send_ua(tRFC_MCB * p_mcb,UINT8 dlci)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 *******************************************************************************/
rfc_send_dm(tRFC_MCB * p_mcb,UINT8 dlci,BOOLEAN pf)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 *******************************************************************************/
rfc_send_disc(tRFC_MCB * p_mcb,UINT8 dlci)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 *******************************************************************************/
rfc_send_buf_uih(tRFC_MCB * p_mcb,UINT8 dlci,BT_HDR * p_buf)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 *******************************************************************************/
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 *)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 *******************************************************************************/
rfc_send_fcon(tRFC_MCB * p_mcb,BOOLEAN is_command)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 *******************************************************************************/
rfc_send_fcoff(tRFC_MCB * p_mcb,BOOLEAN is_command)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 *******************************************************************************/
rfc_send_msc(tRFC_MCB * p_mcb,UINT8 dlci,BOOLEAN is_command,tPORT_CTRL * p_pars)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 *******************************************************************************/
rfc_send_rls(tRFC_MCB * p_mcb,UINT8 dlci,BOOLEAN is_command,UINT8 status)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 *******************************************************************************/
rfc_send_nsc(tRFC_MCB * p_mcb)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 *******************************************************************************/
rfc_send_rpn(tRFC_MCB * p_mcb,UINT8 dlci,BOOLEAN is_command,tPORT_STATE * p_pars,UINT16 mask)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 *******************************************************************************/
rfc_send_test(tRFC_MCB * p_mcb,BOOLEAN is_command,BT_HDR * p_buf)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 *******************************************************************************/
rfc_send_credit(tRFC_MCB * p_mcb,UINT8 dlci,UINT8 credit)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 *******************************************************************************/
rfc_parse_data(tRFC_MCB * p_mcb,MX_FRAME * p_frame,BT_HDR * p_buf)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 *******************************************************************************/
rfc_process_mx_message(tRFC_MCB * p_mcb,BT_HDR * p_buf)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