• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 2006-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 module contains the action functions associated with the channel
22  *  control block state machine.
23  *
24  ******************************************************************************/
25 
26 #include <string.h>
27 #include "data_types.h"
28 #include "bt_target.h"
29 #include "avdt_api.h"
30 #include "avdtc_api.h"
31 #include "avdt_int.h"
32 #include "gki.h"
33 #include "btu.h"
34 #include "btm_api.h"
35 
36 /*******************************************************************************
37 **
38 ** Function         avdt_ccb_clear_ccb
39 **
40 ** Description      This function clears out certain buffers, queues, and
41 **                  other data elements of a ccb.
42 **
43 **
44 ** Returns          void.
45 **
46 *******************************************************************************/
avdt_ccb_clear_ccb(tAVDT_CCB * p_ccb)47 static void avdt_ccb_clear_ccb(tAVDT_CCB *p_ccb)
48 {
49     BT_HDR          *p_buf;
50 
51     /* clear certain ccb variables */
52     p_ccb->cong = FALSE;
53     p_ccb->ret_count = 0;
54 
55     /* free message being fragmented */
56     if (p_ccb->p_curr_msg != NULL)
57     {
58         GKI_freebuf(p_ccb->p_curr_msg);
59         p_ccb->p_curr_msg = NULL;
60     }
61 
62     /* free message being reassembled */
63     if (p_ccb->p_rx_msg != NULL)
64     {
65         GKI_freebuf(p_ccb->p_rx_msg);
66         p_ccb->p_rx_msg = NULL;
67     }
68 
69     /* clear out response queue */
70     while ((p_buf = (BT_HDR *) GKI_dequeue(&p_ccb->rsp_q)) != NULL)
71     {
72         GKI_freebuf(p_buf);
73     }
74 }
75 
76 /*******************************************************************************
77 **
78 ** Function         avdt_ccb_chan_open
79 **
80 ** Description      This function calls avdt_ad_open_req() to
81 **                  initiate a signaling channel connection.
82 **
83 **
84 ** Returns          void.
85 **
86 *******************************************************************************/
avdt_ccb_chan_open(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)87 void avdt_ccb_chan_open(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
88 {
89     BTM_SetOutService(p_ccb->peer_addr, BTM_SEC_SERVICE_AVDTP, AVDT_CHAN_SIG);
90     avdt_ad_open_req(AVDT_CHAN_SIG, p_ccb, NULL, AVDT_INT);
91 }
92 
93 /*******************************************************************************
94 **
95 ** Function         avdt_ccb_chan_close
96 **
97 ** Description      This function calls avdt_ad_close_req() to close a
98 **                  signaling channel connection.
99 **
100 **
101 ** Returns          void.
102 **
103 *******************************************************************************/
avdt_ccb_chan_close(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)104 void avdt_ccb_chan_close(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
105 {
106     /* close the transport channel used by this CCB */
107     avdt_ad_close_req(AVDT_CHAN_SIG, p_ccb, NULL);
108 }
109 
110 /*******************************************************************************
111 **
112 ** Function         avdt_ccb_chk_close
113 **
114 ** Description      This function checks for active streams on this CCB.
115 **                  If there are none, it starts an idle timer.
116 **
117 **
118 ** Returns          void.
119 **
120 *******************************************************************************/
avdt_ccb_chk_close(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)121 void avdt_ccb_chk_close(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
122 {
123     int         i;
124     tAVDT_SCB   *p_scb = &avdt_cb.scb[0];
125 
126     /* see if there are any active scbs associated with this ccb */
127     for (i = 0; i < AVDT_NUM_SEPS; i++, p_scb++)
128     {
129         if ((p_scb->allocated) && (p_scb->p_ccb == p_ccb))
130         {
131             break;
132         }
133     }
134 
135     /* if no active scbs start idle timer */
136     if (i == AVDT_NUM_SEPS)
137     {
138         btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_AVDT_CCB_IDLE, avdt_cb.rcb.idle_tout);
139     }
140 }
141 
142 /*******************************************************************************
143 **
144 ** Function         avdt_ccb_hdl_discover_cmd
145 **
146 ** Description      This function is called when a discover command is
147 **                  received from the peer.  It gathers up the stream
148 **                  information for all allocated streams and initiates
149 **                  sending of a discover response.
150 **
151 **
152 ** Returns          void.
153 **
154 *******************************************************************************/
avdt_ccb_hdl_discover_cmd(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)155 void avdt_ccb_hdl_discover_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
156 {
157     tAVDT_SEP_INFO      sep_info[AVDT_NUM_SEPS];
158     tAVDT_SCB           *p_scb = &avdt_cb.scb[0];
159     int                 i;
160 
161     p_data->msg.discover_rsp.p_sep_info = sep_info;
162     p_data->msg.discover_rsp.num_seps = 0;
163 
164     /* for all allocated scbs */
165     for (i = 0; i < AVDT_NUM_SEPS; i++, p_scb++)
166     {
167         if (p_scb->allocated)
168         {
169             /* copy sep info */
170             sep_info[i].in_use = p_scb->in_use;
171             sep_info[i].seid = i + 1;
172             sep_info[i].media_type = p_scb->cs.media_type;
173             sep_info[i].tsep = p_scb->cs.tsep;
174 
175             p_data->msg.discover_rsp.num_seps++;
176         }
177     }
178 
179     /* send response */
180     avdt_ccb_event(p_ccb, AVDT_CCB_API_DISCOVER_RSP_EVT, p_data);
181 }
182 
183 /*******************************************************************************
184 **
185 ** Function         avdt_ccb_hdl_discover_rsp
186 **
187 ** Description      This function is called when a discover response or
188 **                  reject is received from the peer.  It calls the application
189 **                  callback function with the results.
190 **
191 **
192 ** Returns          void.
193 **
194 *******************************************************************************/
avdt_ccb_hdl_discover_rsp(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)195 void avdt_ccb_hdl_discover_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
196 {
197     /* we're done with procedure */
198     p_ccb->proc_busy = FALSE;
199 
200     /* call app callback with results */
201     (*p_ccb->proc_cback)(0, p_ccb->peer_addr, AVDT_DISCOVER_CFM_EVT,
202                          (tAVDT_CTRL *)(&p_data->msg.discover_rsp));
203 }
204 
205 /*******************************************************************************
206 **
207 ** Function         avdt_ccb_hdl_getcap_cmd
208 **
209 ** Description      This function is called when a get capabilities command
210 **                  is received from the peer.  It retrieves the stream
211 **                  configuration for the requested stream and initiates
212 **                  sending of a get capabilities response.
213 **
214 **
215 ** Returns          void.
216 **
217 *******************************************************************************/
avdt_ccb_hdl_getcap_cmd(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)218 void avdt_ccb_hdl_getcap_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
219 {
220     tAVDT_SCB       *p_scb;
221 
222     /* look up scb for seid sent to us */
223     p_scb = avdt_scb_by_hdl(p_data->msg.single.seid);
224 
225     p_data->msg.svccap.p_cfg = &p_scb->cs.cfg;
226 
227     avdt_ccb_event(p_ccb, AVDT_CCB_API_GETCAP_RSP_EVT, p_data);
228 }
229 
230 /*******************************************************************************
231 **
232 ** Function         avdt_ccb_hdl_getcap_rsp
233 **
234 ** Description      This function is called with a get capabilities response
235 **                  or reject is received from the peer.  It calls the
236 **                  application callback function with the results.
237 **
238 **
239 ** Returns          void.
240 **
241 *******************************************************************************/
avdt_ccb_hdl_getcap_rsp(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)242 void avdt_ccb_hdl_getcap_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
243 {
244     /* we're done with procedure */
245     p_ccb->proc_busy = FALSE;
246 
247     /* call app callback with results */
248     (*p_ccb->proc_cback)(0, p_ccb->peer_addr, AVDT_GETCAP_CFM_EVT,
249                          (tAVDT_CTRL *)(&p_data->msg.svccap));
250 }
251 
252 /*******************************************************************************
253 **
254 ** Function         avdt_ccb_hdl_start_cmd
255 **
256 ** Description      This function is called when a start command is received
257 **                  from the peer.  It verifies that all requested streams
258 **                  are in the proper state.  If so, it initiates sending of
259 **                  a start response.  Otherwise it sends a start reject.
260 **
261 **
262 ** Returns          void.
263 **
264 *******************************************************************************/
avdt_ccb_hdl_start_cmd(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)265 void avdt_ccb_hdl_start_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
266 {
267     UINT8   seid;
268     UINT8   err_code;
269 
270     /* verify all streams in the right state */
271     if ((seid = avdt_scb_verify(p_ccb, AVDT_VERIFY_START, p_data->msg.multi.seid_list,
272                                 p_data->msg.multi.num_seps, &err_code)) == 0)
273     {
274         /* we're ok, send response */
275         avdt_ccb_event(p_ccb, AVDT_CCB_API_START_RSP_EVT, p_data);
276     }
277     else
278     {
279         /* not ok, send reject */
280         p_data->msg.hdr.err_code = err_code;
281         p_data->msg.hdr.err_param = seid;
282         avdt_msg_send_rej(p_ccb, AVDT_SIG_START, &p_data->msg);
283     }
284 }
285 
286 /*******************************************************************************
287 **
288 ** Function         avdt_ccb_hdl_start_rsp
289 **
290 ** Description      This function is called when a start response or reject
291 **                  is received from the peer.  Using the SEIDs stored in the
292 **                  current command message, it sends a start response or start
293 **                  reject event to each SCB associated with the command.
294 **
295 **
296 ** Returns          void.
297 **
298 *******************************************************************************/
avdt_ccb_hdl_start_rsp(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)299 void avdt_ccb_hdl_start_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
300 {
301     UINT8       event;
302     int         i;
303     UINT8       *p;
304     tAVDT_SCB   *p_scb;
305 
306     /* determine rsp or rej event */
307     event = (p_data->msg.hdr.err_code == 0) ?
308             AVDT_SCB_MSG_START_RSP_EVT : AVDT_SCB_MSG_START_REJ_EVT;
309 
310     /* get to where seid's are stashed in current cmd */
311     p = (UINT8 *)(p_ccb->p_curr_cmd + 1);
312 
313     /* little trick here; length of current command equals number of streams */
314     for (i = 0; i < p_ccb->p_curr_cmd->len; i++)
315     {
316         if ((p_scb = avdt_scb_by_hdl(p[i])) != NULL)
317         {
318             avdt_scb_event(p_scb, event, (tAVDT_SCB_EVT *) &p_data->msg);
319         }
320     }
321 }
322 
323 /*******************************************************************************
324 **
325 ** Function         avdt_ccb_hdl_suspend_cmd
326 **
327 ** Description      This function is called when a suspend command is received
328 **                  from the peer.  It verifies that all requested streams are
329 **                  in the proper state.  If so, it initiates sending of a
330 **                  suspend response.  Otherwise it sends a suspend reject.
331 
332 **
333 **
334 ** Returns          void.
335 **
336 *******************************************************************************/
avdt_ccb_hdl_suspend_cmd(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)337 void avdt_ccb_hdl_suspend_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
338 {
339     UINT8   seid;
340     UINT8   err_code;
341 
342     /* verify all streams in the right state */
343     if ((seid = avdt_scb_verify(p_ccb, AVDT_VERIFY_SUSPEND, p_data->msg.multi.seid_list,
344                                 p_data->msg.multi.num_seps, &err_code)) == 0)
345     {
346         /* we're ok, send response */
347         avdt_ccb_event(p_ccb, AVDT_CCB_API_SUSPEND_RSP_EVT, p_data);
348     }
349     else
350     {
351         /* not ok, send reject */
352         p_data->msg.hdr.err_code = err_code;
353         p_data->msg.hdr.err_param = seid;
354         avdt_msg_send_rej(p_ccb, AVDT_SIG_SUSPEND, &p_data->msg);
355     }
356 }
357 
358 /*******************************************************************************
359 **
360 ** Function         avdt_ccb_hdl_suspend_rsp
361 **
362 ** Description      This function is called when a suspend response or reject
363 **                  is received from the peer.  Using the SEIDs stored in the
364 **                  current command message, it sends a suspend response or
365 **                  suspend reject event to each SCB associated with the command.
366 **
367 **
368 **
369 ** Returns          void.
370 **
371 *******************************************************************************/
avdt_ccb_hdl_suspend_rsp(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)372 void avdt_ccb_hdl_suspend_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
373 {
374     UINT8       event;
375     int         i;
376     UINT8       *p;
377     tAVDT_SCB   *p_scb;
378 
379     /* determine rsp or rej event */
380     event = (p_data->msg.hdr.err_code == 0) ?
381             AVDT_SCB_MSG_SUSPEND_RSP_EVT : AVDT_SCB_MSG_SUSPEND_REJ_EVT;
382 
383     /* get to where seid's are stashed in current cmd */
384     p = (UINT8 *)(p_ccb->p_curr_cmd + 1);
385 
386     /* little trick here; length of current command equals number of streams */
387     for (i = 0; i < p_ccb->p_curr_cmd->len; i++)
388     {
389         if ((p_scb = avdt_scb_by_hdl(p[i])) != NULL)
390         {
391             avdt_scb_event(p_scb, event, (tAVDT_SCB_EVT *) &p_data->msg);
392         }
393     }
394 }
395 
396 /*******************************************************************************
397 **
398 ** Function         avdt_ccb_snd_discover_cmd
399 **
400 ** Description      This function is called to send a discover command to the
401 **                  peer.  It copies variables needed for the procedure from
402 **                  the event to the CCB.  It marks the CCB as busy and then
403 **                  sends a discover command.
404 **
405 **
406 ** Returns          void.
407 **
408 *******************************************************************************/
avdt_ccb_snd_discover_cmd(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)409 void avdt_ccb_snd_discover_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
410 {
411     /* store info in ccb struct */
412     p_ccb->p_proc_data = p_data->discover.p_sep_info;
413     p_ccb->proc_cback = p_data->discover.p_cback;
414     p_ccb->proc_param = p_data->discover.num_seps;
415 
416     /* we're busy */
417     p_ccb->proc_busy = TRUE;
418 
419     /* build and queue discover req */
420     avdt_msg_send_cmd(p_ccb, NULL, AVDT_SIG_DISCOVER, NULL);
421 }
422 
423 /*******************************************************************************
424 **
425 ** Function         avdt_ccb_snd_discover_rsp
426 **
427 ** Description      This function is called to send a discover response to
428 **                  the peer.  It takes the stream information passed in the
429 **                  event and sends a discover response.
430 **
431 **
432 ** Returns          void.
433 **
434 *******************************************************************************/
avdt_ccb_snd_discover_rsp(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)435 void avdt_ccb_snd_discover_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
436 {
437     /* send response */
438     avdt_msg_send_rsp(p_ccb, AVDT_SIG_DISCOVER, &p_data->msg);
439 }
440 
441 /*******************************************************************************
442 **
443 ** Function         avdt_ccb_snd_getcap_cmd
444 **
445 ** Description      This function is called to send a get capabilities command
446 **                  to the peer.  It copies variables needed for the procedure
447 **                  from the event to the CCB.  It marks the CCB as busy and
448 **                  then sends a get capabilities command.
449 **
450 **
451 ** Returns          void.
452 **
453 *******************************************************************************/
avdt_ccb_snd_getcap_cmd(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)454 void avdt_ccb_snd_getcap_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
455 {
456     UINT8 sig_id = AVDT_SIG_GETCAP;
457 
458     /* store info in ccb struct */
459     p_ccb->p_proc_data = p_data->getcap.p_cfg;
460     p_ccb->proc_cback = p_data->getcap.p_cback;
461 
462     /* we're busy */
463     p_ccb->proc_busy = TRUE;
464 
465     /* build and queue discover req */
466     if (p_data->msg.hdr.sig_id == AVDT_SIG_GET_ALLCAP)
467         sig_id = AVDT_SIG_GET_ALLCAP;
468 
469     avdt_msg_send_cmd(p_ccb, NULL, sig_id, (tAVDT_MSG *) &p_data->getcap.single);
470 }
471 
472 /*******************************************************************************
473 **
474 ** Function         avdt_ccb_snd_getcap_rsp
475 **
476 ** Description      This function is called to send a get capabilities response
477 **                  to the peer.  It takes the stream information passed in the
478 **                  event and sends a get capabilities response.
479 **
480 **
481 ** Returns          void.
482 **
483 *******************************************************************************/
avdt_ccb_snd_getcap_rsp(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)484 void avdt_ccb_snd_getcap_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
485 {
486     UINT8 sig_id = AVDT_SIG_GETCAP;
487 
488     if (p_data->msg.hdr.sig_id == AVDT_SIG_GET_ALLCAP)
489         sig_id = AVDT_SIG_GET_ALLCAP;
490 
491     /* send response */
492     avdt_msg_send_rsp(p_ccb, sig_id, &p_data->msg);
493 }
494 
495 /*******************************************************************************
496 **
497 ** Function         avdt_ccb_snd_start_cmd
498 **
499 ** Description      This function is called to send a start command to the
500 **                  peer.  It verifies that all requested streams are in the
501 **                  proper state.  If so, it sends a start command.  Otherwise
502 **                  send ourselves back a start reject.
503 **
504 **
505 ** Returns          void.
506 **
507 *******************************************************************************/
avdt_ccb_snd_start_cmd(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)508 void avdt_ccb_snd_start_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
509 {
510     int             i;
511     tAVDT_SCB       *p_scb;
512     tAVDT_MSG       avdt_msg;
513     UINT8           seid_list[AVDT_NUM_SEPS];
514 
515     /* make copy of our seid list */
516     memcpy(seid_list, p_data->msg.multi.seid_list, p_data->msg.multi.num_seps);
517 
518     /* verify all streams in the right state */
519     if ((avdt_msg.hdr.err_param = avdt_scb_verify(p_ccb, AVDT_VERIFY_OPEN, p_data->msg.multi.seid_list,
520                                          p_data->msg.multi.num_seps, &avdt_msg.hdr.err_code)) == 0)
521     {
522         /* set peer seid list in messsage */
523         avdt_scb_peer_seid_list(&p_data->msg.multi);
524 
525         /* send command */
526         avdt_msg_send_cmd(p_ccb, seid_list, AVDT_SIG_START, &p_data->msg);
527     }
528     else
529     {
530         /* failed; send ourselves a reject for each stream */
531         for (i = 0; i < p_data->msg.multi.num_seps; i++)
532         {
533             if ((p_scb = avdt_scb_by_hdl(seid_list[i])) != NULL)
534             {
535                 avdt_scb_event(p_scb, AVDT_SCB_MSG_START_REJ_EVT, (tAVDT_SCB_EVT *) &avdt_msg.hdr);
536             }
537         }
538     }
539 }
540 
541 /*******************************************************************************
542 **
543 ** Function         avdt_ccb_snd_start_rsp
544 **
545 ** Description      This function is called to send a start response to the
546 **                  peer.  It takes the stream information passed in the event
547 **                  and sends a start response.  Then it sends a start event
548 **                  to the SCB for each stream.
549 **
550 **
551 ** Returns          void.
552 **
553 *******************************************************************************/
avdt_ccb_snd_start_rsp(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)554 void avdt_ccb_snd_start_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
555 {
556     tAVDT_SCB *p_scb;
557     int i;
558 
559     /* send response message */
560     avdt_msg_send_rsp(p_ccb, AVDT_SIG_START, &p_data->msg);
561 
562     /* send start event to each scb */
563     for (i = 0; i < p_data->msg.multi.num_seps; i++)
564     {
565         if ((p_scb = avdt_scb_by_hdl(p_data->msg.multi.seid_list[i])) != NULL)
566         {
567             avdt_scb_event(p_scb, AVDT_SCB_MSG_START_CMD_EVT, NULL);
568         }
569     }
570 }
571 
572 /*******************************************************************************
573 **
574 ** Function         avdt_ccb_snd_suspend_cmd
575 **
576 ** Description      This function is called to send a suspend command to the
577 **                  peer.  It verifies that all requested streams are in the
578 **                  proper state.  If so, it sends a suspend command.
579 **                  Otherwise it calls the callback function for each requested
580 **                  stream and sends a suspend confirmation with failure.
581 **
582 **
583 ** Returns          void.
584 **
585 *******************************************************************************/
avdt_ccb_snd_suspend_cmd(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)586 void avdt_ccb_snd_suspend_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
587 {
588     int             i;
589     tAVDT_SCB       *p_scb;
590     tAVDT_MSG       avdt_msg;
591     UINT8           seid_list[AVDT_NUM_SEPS];
592 
593     /* make copy of our seid list */
594     memcpy(seid_list, p_data->msg.multi.seid_list, p_data->msg.multi.num_seps);
595 
596     /* verify all streams in the right state */
597     if ((avdt_msg.hdr.err_param = avdt_scb_verify(p_ccb, AVDT_VERIFY_STREAMING, p_data->msg.multi.seid_list,
598                                          p_data->msg.multi.num_seps, &avdt_msg.hdr.err_code)) == 0)
599     {
600         /* set peer seid list in messsage */
601         avdt_scb_peer_seid_list(&p_data->msg.multi);
602 
603         /* send command */
604         avdt_msg_send_cmd(p_ccb, seid_list, AVDT_SIG_SUSPEND, &p_data->msg);
605     }
606     else
607     {
608         /* failed; send ourselves a reject for each stream */
609         for (i = 0; i < p_data->msg.multi.num_seps; i++)
610         {
611             if ((p_scb = avdt_scb_by_hdl(seid_list[i])) != NULL)
612             {
613                 avdt_scb_event(p_scb, AVDT_SCB_MSG_SUSPEND_REJ_EVT, (tAVDT_SCB_EVT *) &avdt_msg.hdr);
614             }
615         }
616     }
617 }
618 
619 /*******************************************************************************
620 **
621 ** Function         avdt_ccb_snd_suspend_rsp
622 **
623 ** Description      This function is called to send a suspend response to the
624 **                  peer.  It takes the stream information passed in the event
625 **                  and sends a suspend response.  Then it sends a suspend event
626 **                  to the SCB for each stream.
627 **
628 **
629 ** Returns          void.
630 **
631 *******************************************************************************/
avdt_ccb_snd_suspend_rsp(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)632 void avdt_ccb_snd_suspend_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
633 {
634     tAVDT_SCB *p_scb;
635     int i;
636 
637     /* send response message */
638     avdt_msg_send_rsp(p_ccb, AVDT_SIG_SUSPEND, &p_data->msg);
639 
640     /* send start event to each scb */
641     for (i = 0; i < p_data->msg.multi.num_seps; i++)
642     {
643         if ((p_scb = avdt_scb_by_hdl(p_data->msg.multi.seid_list[i])) != NULL)
644         {
645             avdt_scb_event(p_scb, AVDT_SCB_MSG_SUSPEND_CMD_EVT, NULL);
646         }
647     }
648 }
649 
650 /*******************************************************************************
651 **
652 ** Function         avdt_ccb_clear_cmds
653 **
654 ** Description      This function is called when the signaling channel is
655 **                  closed to clean up any pending commands.  For each pending
656 **                  command in the command queue, it frees the command and
657 **                  calls the application callback function indicating failure.
658 **                  Certain CCB variables are also initialized.
659 **
660 **
661 ** Returns          void.
662 **
663 *******************************************************************************/
avdt_ccb_clear_cmds(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)664 void avdt_ccb_clear_cmds(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
665 {
666     int             i;
667     tAVDT_SCB       *p_scb = &avdt_cb.scb[0];
668     UINT8           err_code = AVDT_ERR_CONNECT;
669 
670     /* clear the ccb */
671     avdt_ccb_clear_ccb(p_ccb);
672 
673     /* clear out command queue; this is a little tricky here; we need
674     ** to handle the case where there is a command on deck in p_curr_cmd,
675     ** plus we need to clear out the queue
676     */
677     do
678     {
679         /* we know p_curr_cmd = NULL after this */
680         avdt_ccb_cmd_fail(p_ccb, (tAVDT_CCB_EVT *) &err_code);
681 
682         /* set up next message */
683         p_ccb->p_curr_cmd = (BT_HDR *) GKI_dequeue(&p_ccb->cmd_q);
684 
685     } while (p_ccb->p_curr_cmd != NULL);
686 
687     /* send a CC_CLOSE_EVT any active scbs associated with this ccb */
688     for (i = 0; i < AVDT_NUM_SEPS; i++, p_scb++)
689     {
690         if ((p_scb->allocated) && (p_scb->p_ccb == p_ccb))
691         {
692             avdt_scb_event(p_scb, AVDT_SCB_CC_CLOSE_EVT, NULL);
693         }
694     }
695 }
696 
697 /*******************************************************************************
698 **
699 ** Function         avdt_ccb_cmd_fail
700 **
701 ** Description      This function is called when there is a response timeout.
702 **                  The currently pending command is freed and we fake a
703 **                  reject message back to ourselves.
704 **
705 **
706 ** Returns          void.
707 **
708 *******************************************************************************/
avdt_ccb_cmd_fail(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)709 void avdt_ccb_cmd_fail(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
710 {
711     tAVDT_MSG       msg;
712     UINT8           evt;
713     tAVDT_SCB       *p_scb;
714 
715     if (p_ccb->p_curr_cmd != NULL)
716     {
717         /* set up data */
718         msg.hdr.err_code = p_data->err_code;
719         msg.hdr.err_param = 0;
720         msg.hdr.ccb_idx = avdt_ccb_to_idx(p_ccb);
721 
722         /* pretend that we received a rej message */
723         evt = avdt_msg_rej_2_evt[p_ccb->p_curr_cmd->event - 1];
724 
725         if (evt & AVDT_CCB_MKR)
726         {
727             avdt_ccb_event(p_ccb, (UINT8) (evt & ~AVDT_CCB_MKR), (tAVDT_CCB_EVT *) &msg);
728         }
729         else
730         {
731             /* we get the scb out of the current cmd */
732             p_scb = avdt_scb_by_hdl(*((UINT8 *)(p_ccb->p_curr_cmd + 1)));
733             if (p_scb != NULL)
734             {
735                 avdt_scb_event(p_scb, evt, (tAVDT_SCB_EVT *) &msg);
736             }
737         }
738 
739         GKI_freebuf(p_ccb->p_curr_cmd);
740         p_ccb->p_curr_cmd = NULL;
741     }
742 }
743 
744 /*******************************************************************************
745 **
746 ** Function         avdt_ccb_free_cmd
747 **
748 ** Description      This function is called when a response is received for a
749 **                  currently pending command.  The command is freed.
750 **
751 **
752 ** Returns          void.
753 **
754 *******************************************************************************/
avdt_ccb_free_cmd(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)755 void avdt_ccb_free_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
756 {
757     if (p_ccb->p_curr_cmd != NULL)
758     {
759         GKI_freebuf(p_ccb->p_curr_cmd);
760         p_ccb->p_curr_cmd = NULL;
761     }
762 }
763 
764 /*******************************************************************************
765 **
766 ** Function         avdt_ccb_cong_state
767 **
768 ** Description      This function is called to set the congestion state for
769 **                  the CCB.
770 **
771 **
772 ** Returns          void.
773 **
774 *******************************************************************************/
avdt_ccb_cong_state(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)775 void avdt_ccb_cong_state(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
776 {
777     p_ccb->cong = p_data->llcong;
778 }
779 
780 /*******************************************************************************
781 **
782 ** Function         avdt_ccb_ret_cmd
783 **
784 ** Description      This function is called to retransmit the currently
785 **                  pending command.  The retransmission count is incremented.
786 **                  If the count reaches the maximum number of retransmissions,
787 **                  the event is treated as a response timeout.
788 **
789 **
790 ** Returns          void.
791 **
792 *******************************************************************************/
avdt_ccb_ret_cmd(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)793 void avdt_ccb_ret_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
794 {
795     UINT8   err_code = AVDT_ERR_TIMEOUT;
796     BT_HDR  *p_msg;
797 
798     p_ccb->ret_count++;
799     if (p_ccb->ret_count == AVDT_RET_MAX)
800     {
801         /* command failed */
802         p_ccb->ret_count = 0;
803         avdt_ccb_cmd_fail(p_ccb, (tAVDT_CCB_EVT *) &err_code);
804 
805         /* go to next queued command */
806         avdt_ccb_snd_cmd(p_ccb, p_data);
807     }
808     else
809     {
810         /* if command pending and we're not congested and not sending a fragment */
811         if ((!p_ccb->cong) && (p_ccb->p_curr_msg == NULL) && (p_ccb->p_curr_cmd != NULL))
812         {
813             /* make copy of message in p_curr_cmd and send it */
814             if ((p_msg = (BT_HDR *) GKI_getpoolbuf(AVDT_CMD_POOL_ID)) != NULL)
815             {
816                 memcpy(p_msg, p_ccb->p_curr_cmd,
817                        (sizeof(BT_HDR) + p_ccb->p_curr_cmd->offset + p_ccb->p_curr_cmd->len));
818                 avdt_msg_send(p_ccb, p_msg);
819             }
820         }
821 
822         /* restart timer */
823         btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_AVDT_CCB_RET, avdt_cb.rcb.ret_tout);
824     }
825 }
826 
827 /*******************************************************************************
828 **
829 ** Function         avdt_ccb_snd_cmd
830 **
831 ** Description      This function is called the send the next command,
832 **                  if any, in the command queue.
833 **
834 **
835 ** Returns          void.
836 **
837 *******************************************************************************/
avdt_ccb_snd_cmd(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)838 void avdt_ccb_snd_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
839 {
840     BT_HDR  *p_msg;
841 
842     /* do we have commands to send?  send next command;  make sure we're clear;
843     ** not congested, not sending fragment, not waiting for response
844     */
845     if ((!p_ccb->cong) && (p_ccb->p_curr_msg == NULL) && (p_ccb->p_curr_cmd == NULL))
846     {
847         if ((p_msg = (BT_HDR *) GKI_dequeue(&p_ccb->cmd_q)) != NULL)
848         {
849             /* make a copy of buffer in p_curr_cmd */
850             if ((p_ccb->p_curr_cmd = (BT_HDR *) GKI_getpoolbuf(AVDT_CMD_POOL_ID)) != NULL)
851             {
852                 memcpy(p_ccb->p_curr_cmd, p_msg, (sizeof(BT_HDR) + p_msg->offset + p_msg->len));
853 
854                 avdt_msg_send(p_ccb, p_msg);
855             }
856         }
857     }
858 }
859 
860 /*******************************************************************************
861 **
862 ** Function         avdt_ccb_snd_msg
863 **
864 ** Description
865 **
866 **
867 ** Returns          void.
868 **
869 *******************************************************************************/
avdt_ccb_snd_msg(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)870 void avdt_ccb_snd_msg(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
871 {
872     BT_HDR      *p_msg;
873 
874     /* if not congested */
875     if (!p_ccb->cong)
876     {
877         /* are we sending a fragmented message? continue sending fragment */
878         if (p_ccb->p_curr_msg != NULL)
879         {
880             avdt_msg_send(p_ccb, NULL);
881         }
882         /* do we have responses to send?  send them */
883         else if (!GKI_queue_is_empty(&p_ccb->rsp_q))
884         {
885             while ((p_msg = (BT_HDR *) GKI_dequeue(&p_ccb->rsp_q)) != NULL)
886             {
887                 if (avdt_msg_send(p_ccb, p_msg) == TRUE)
888                 {
889                     /* break out if congested */
890                     break;
891                 }
892             }
893         }
894 
895         /* do we have commands to send?  send next command */
896         avdt_ccb_snd_cmd(p_ccb, NULL);
897     }
898 }
899 
900 /*******************************************************************************
901 **
902 ** Function         avdt_ccb_set_reconn
903 **
904 ** Description      This function is called to enable a reconnect attempt when
905 **                  a channel transitions from closing to idle state.  It sets
906 **                  the reconn variable to TRUE.
907 **
908 **
909 ** Returns          void.
910 **
911 *******************************************************************************/
avdt_ccb_set_reconn(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)912 void avdt_ccb_set_reconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
913 {
914     p_ccb->reconn = TRUE;
915 }
916 
917 /*******************************************************************************
918 **
919 ** Function         avdt_ccb_clr_reconn
920 **
921 ** Description      This function is called to clear the reconn variable.
922 **
923 **
924 ** Returns          void.
925 **
926 *******************************************************************************/
avdt_ccb_clr_reconn(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)927 void avdt_ccb_clr_reconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
928 {
929     p_ccb->reconn = FALSE;
930 }
931 
932 /*******************************************************************************
933 **
934 ** Function         avdt_ccb_chk_reconn
935 **
936 ** Description      This function is called to check if a reconnect attempt
937 **                  is enabled.  If enabled, it sends an AVDT_CCB_UL_OPEN_EVT
938 **                  to the CCB.  If disabled, the CCB is deallocated.
939 **
940 **
941 ** Returns          void.
942 **
943 *******************************************************************************/
avdt_ccb_chk_reconn(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)944 void avdt_ccb_chk_reconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
945 {
946     UINT8   err_code = AVDT_ERR_CONNECT;
947 
948     if (p_ccb->reconn)
949     {
950         p_ccb->reconn = FALSE;
951 
952         /* clear out ccb */
953         avdt_ccb_clear_ccb(p_ccb);
954 
955         /* clear out current command, if any */
956         avdt_ccb_cmd_fail(p_ccb, (tAVDT_CCB_EVT *) &err_code);
957 
958         /* reopen the signaling channel */
959         avdt_ccb_event(p_ccb, AVDT_CCB_UL_OPEN_EVT, NULL);
960     }
961     else
962     {
963         avdt_ccb_ll_closed(p_ccb, NULL);
964     }
965 }
966 
967 /*******************************************************************************
968 **
969 ** Function         avdt_ccb_chk_timer
970 **
971 ** Description      This function stops the CCB timer if the idle timer is
972 **                  running.
973 **
974 **
975 ** Returns          void.
976 **
977 *******************************************************************************/
avdt_ccb_chk_timer(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)978 void avdt_ccb_chk_timer(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
979 {
980     if (p_ccb->timer_entry.event == BTU_TTYPE_AVDT_CCB_IDLE)
981     {
982         btu_stop_timer(&p_ccb->timer_entry);
983     }
984 }
985 
986 /*******************************************************************************
987 **
988 ** Function         avdt_ccb_set_conn
989 **
990 ** Description      Set CCB variables associated with AVDT_ConnectReq().
991 **
992 **
993 ** Returns          void.
994 **
995 *******************************************************************************/
avdt_ccb_set_conn(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)996 void avdt_ccb_set_conn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
997 {
998     /* save callback */
999     p_ccb->p_conn_cback = p_data->connect.p_cback;
1000 
1001     /* set security level */
1002     BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_AVDTP, p_data->connect.sec_mask,
1003                          AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_SIG);
1004 }
1005 
1006 /*******************************************************************************
1007 **
1008 ** Function         avdt_ccb_set_disconn
1009 **
1010 ** Description      Set CCB variables associated with AVDT_DisconnectReq().
1011 **
1012 **
1013 ** Returns          void.
1014 **
1015 *******************************************************************************/
avdt_ccb_set_disconn(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)1016 void avdt_ccb_set_disconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
1017 {
1018     /*
1019     AVDT_TRACE_EVENT2("avdt_ccb_set_disconn:conn:x%x, api:x%x",
1020         p_ccb->p_conn_cback, p_data->disconnect.p_cback);
1021         */
1022     /* save callback */
1023     if (p_data->disconnect.p_cback)
1024         p_ccb->p_conn_cback = p_data->disconnect.p_cback;
1025 }
1026 
1027 /*******************************************************************************
1028 **
1029 ** Function         avdt_ccb_do_disconn
1030 **
1031 ** Description      Do action associated with AVDT_DisconnectReq().
1032 **
1033 **
1034 ** Returns          void.
1035 **
1036 *******************************************************************************/
avdt_ccb_do_disconn(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)1037 void avdt_ccb_do_disconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
1038 {
1039     /* clear any pending commands */
1040     avdt_ccb_clear_cmds(p_ccb, NULL);
1041 
1042     /* close channel */
1043     avdt_ccb_chan_close(p_ccb, NULL);
1044 }
1045 
1046 /*******************************************************************************
1047 **
1048 ** Function         avdt_ccb_ll_closed
1049 **
1050 ** Description      Clear commands from and deallocate CCB.
1051 **
1052 **
1053 ** Returns          void.
1054 **
1055 *******************************************************************************/
avdt_ccb_ll_closed(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)1056 void avdt_ccb_ll_closed(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
1057 {
1058     tAVDT_CTRL_CBACK    *p_cback;
1059     BD_ADDR             bd_addr;
1060     tAVDT_CTRL          avdt_ctrl;
1061 
1062     /* clear any pending commands */
1063     avdt_ccb_clear_cmds(p_ccb, NULL);
1064 
1065     /* save callback pointer, bd addr */
1066     p_cback = p_ccb->p_conn_cback;
1067     if (!p_cback)
1068         p_cback = avdt_cb.p_conn_cback;
1069     memcpy(bd_addr, p_ccb->peer_addr, BD_ADDR_LEN);
1070 
1071     /* dealloc ccb */
1072     avdt_ccb_dealloc(p_ccb, NULL);
1073 
1074     /* call callback */
1075     if (p_cback)
1076     {
1077         avdt_ctrl.hdr.err_code = 0;
1078         (*p_cback)(0, bd_addr, AVDT_DISCONNECT_IND_EVT, &avdt_ctrl);
1079     }
1080 }
1081 
1082 /*******************************************************************************
1083 **
1084 ** Function         avdt_ccb_ll_opened
1085 **
1086 ** Description      Call callback on open.
1087 **
1088 **
1089 ** Returns          void.
1090 **
1091 *******************************************************************************/
avdt_ccb_ll_opened(tAVDT_CCB * p_ccb,tAVDT_CCB_EVT * p_data)1092 void avdt_ccb_ll_opened(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
1093 {
1094     tAVDT_CTRL          avdt_ctrl;
1095 
1096     p_ccb->ll_opened = TRUE;
1097 
1098     if (!p_ccb->p_conn_cback)
1099         p_ccb->p_conn_cback = avdt_cb.p_conn_cback;
1100 
1101     /* call callback */
1102     if (p_ccb->p_conn_cback)
1103     {
1104         avdt_ctrl.hdr.err_code = 0;
1105         avdt_ctrl.hdr.err_param = p_data->msg.hdr.err_param;
1106         (*p_ccb->p_conn_cback)(0, p_ccb->peer_addr, AVDT_CONNECT_IND_EVT, &avdt_ctrl);
1107     }
1108 }
1109