OSDN Git Service

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