1 /******************************************************************************
3 * Copyright (C) 2006-2012 Broadcom Corporation
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 ******************************************************************************/
19 /******************************************************************************
21 * This module contains the action functions associated with the channel
22 * control block state machine.
24 ******************************************************************************/
28 #include "bt_target.h"
31 #include "avdtc_api.h"
33 #include "bt_common.h"
37 extern fixed_queue_t *btu_general_alarm_queue;
39 /*******************************************************************************
41 ** Function avdt_ccb_clear_ccb
43 ** Description This function clears out certain buffers, queues, and
44 ** other data elements of a ccb.
49 *******************************************************************************/
50 static void avdt_ccb_clear_ccb(tAVDT_CCB *p_ccb)
54 /* clear certain ccb variables */
58 /* free message being fragmented */
59 osi_free_and_reset((void **)&p_ccb->p_curr_msg);
61 /* free message being reassembled */
62 osi_free_and_reset((void **)&p_ccb->p_rx_msg);
64 /* clear out response queue */
65 while ((p_buf = (BT_HDR *) fixed_queue_try_dequeue(p_ccb->rsp_q)) != NULL)
69 /*******************************************************************************
71 ** Function avdt_ccb_chan_open
73 ** Description This function calls avdt_ad_open_req() to
74 ** initiate a signaling channel connection.
79 *******************************************************************************/
80 void avdt_ccb_chan_open(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
84 BTM_SetOutService(p_ccb->peer_addr, BTM_SEC_SERVICE_AVDTP, AVDT_CHAN_SIG);
85 avdt_ad_open_req(AVDT_CHAN_SIG, p_ccb, NULL, AVDT_INT);
88 /*******************************************************************************
90 ** Function avdt_ccb_chan_close
92 ** Description This function calls avdt_ad_close_req() to close a
93 ** signaling channel connection.
98 *******************************************************************************/
99 void avdt_ccb_chan_close(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
103 /* close the transport channel used by this CCB */
104 avdt_ad_close_req(AVDT_CHAN_SIG, p_ccb, NULL);
107 /*******************************************************************************
109 ** Function avdt_ccb_chk_close
111 ** Description This function checks for active streams on this CCB.
112 ** If there are none, it starts an idle timer.
117 *******************************************************************************/
118 void avdt_ccb_chk_close(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
121 tAVDT_SCB *p_scb = &avdt_cb.scb[0];
124 /* see if there are any active scbs associated with this ccb */
125 for (i = 0; i < AVDT_NUM_SEPS; i++, p_scb++)
127 if ((p_scb->allocated) && (p_scb->p_ccb == p_ccb))
133 /* if no active scbs start idle timer */
134 if (i == AVDT_NUM_SEPS)
136 alarm_cancel(p_ccb->ret_ccb_timer);
137 alarm_cancel(p_ccb->rsp_ccb_timer);
138 period_ms_t interval_ms = avdt_cb.rcb.idle_tout * 1000;
139 alarm_set_on_queue(p_ccb->idle_ccb_timer, interval_ms,
140 avdt_ccb_idle_ccb_timer_timeout, p_ccb,
141 btu_general_alarm_queue);
145 /*******************************************************************************
147 ** Function avdt_ccb_hdl_discover_cmd
149 ** Description This function is called when a discover command is
150 ** received from the peer. It gathers up the stream
151 ** information for all allocated streams and initiates
152 ** sending of a discover response.
157 *******************************************************************************/
158 void avdt_ccb_hdl_discover_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
160 tAVDT_SEP_INFO sep_info[AVDT_NUM_SEPS];
161 tAVDT_SCB *p_scb = &avdt_cb.scb[0];
164 p_data->msg.discover_rsp.p_sep_info = sep_info;
165 p_data->msg.discover_rsp.num_seps = 0;
167 /* for all allocated scbs */
168 for (i = 0; i < AVDT_NUM_SEPS; i++, p_scb++)
170 if (p_scb->allocated)
173 sep_info[p_data->msg.discover_rsp.num_seps].in_use = p_scb->in_use;
174 sep_info[p_data->msg.discover_rsp.num_seps].seid = i + 1;
175 sep_info[p_data->msg.discover_rsp.num_seps].media_type = p_scb->cs.media_type;
176 sep_info[p_data->msg.discover_rsp.num_seps].tsep = p_scb->cs.tsep;
178 p_data->msg.discover_rsp.num_seps++;
183 avdt_ccb_event(p_ccb, AVDT_CCB_API_DISCOVER_RSP_EVT, p_data);
186 /*******************************************************************************
188 ** Function avdt_ccb_hdl_discover_rsp
190 ** Description This function is called when a discover response or
191 ** reject is received from the peer. It calls the application
192 ** callback function with the results.
197 *******************************************************************************/
198 void avdt_ccb_hdl_discover_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
200 /* we're done with procedure */
201 p_ccb->proc_busy = FALSE;
203 /* call app callback with results */
204 (*p_ccb->proc_cback)(0, p_ccb->peer_addr, AVDT_DISCOVER_CFM_EVT,
205 (tAVDT_CTRL *)(&p_data->msg.discover_rsp));
208 /*******************************************************************************
210 ** Function avdt_ccb_hdl_getcap_cmd
212 ** Description This function is called when a get capabilities command
213 ** is received from the peer. It retrieves the stream
214 ** configuration for the requested stream and initiates
215 ** sending of a get capabilities response.
220 *******************************************************************************/
221 void avdt_ccb_hdl_getcap_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
225 /* look up scb for seid sent to us */
226 p_scb = avdt_scb_by_hdl(p_data->msg.single.seid);
228 p_data->msg.svccap.p_cfg = &p_scb->cs.cfg;
230 avdt_ccb_event(p_ccb, AVDT_CCB_API_GETCAP_RSP_EVT, p_data);
233 /*******************************************************************************
235 ** Function avdt_ccb_hdl_getcap_rsp
237 ** Description This function is called with a get capabilities response
238 ** or reject is received from the peer. It calls the
239 ** application callback function with the results.
244 *******************************************************************************/
245 void avdt_ccb_hdl_getcap_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
247 /* we're done with procedure */
248 p_ccb->proc_busy = FALSE;
250 /* call app callback with results */
251 (*p_ccb->proc_cback)(0, p_ccb->peer_addr, AVDT_GETCAP_CFM_EVT,
252 (tAVDT_CTRL *)(&p_data->msg.svccap));
255 /*******************************************************************************
257 ** Function avdt_ccb_hdl_start_cmd
259 ** Description This function is called when a start command is received
260 ** from the peer. It verifies that all requested streams
261 ** are in the proper state. If so, it initiates sending of
262 ** a start response. Otherwise it sends a start reject.
267 *******************************************************************************/
268 void avdt_ccb_hdl_start_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
272 /* verify all streams in the right state */
273 UINT8 seid = avdt_scb_verify(p_ccb, AVDT_VERIFY_START, p_data->msg.multi.seid_list,
274 p_data->msg.multi.num_seps, &err_code);
275 if (seid == 0 && err_code == 0)
277 /* we're ok, send response */
278 avdt_ccb_event(p_ccb, AVDT_CCB_API_START_RSP_EVT, p_data);
280 /* not ok, send reject */
281 p_data->msg.hdr.err_code = err_code;
282 p_data->msg.hdr.err_param = seid;
283 avdt_msg_send_rej(p_ccb, AVDT_SIG_START, &p_data->msg);
287 /*******************************************************************************
289 ** Function avdt_ccb_hdl_start_rsp
291 ** Description This function is called when a start response or reject
292 ** is received from the peer. Using the SEIDs stored in the
293 ** current command message, it sends a start response or start
294 ** reject event to each SCB associated with the command.
299 *******************************************************************************/
300 void avdt_ccb_hdl_start_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
307 /* determine rsp or rej event */
308 event = (p_data->msg.hdr.err_code == 0) ?
309 AVDT_SCB_MSG_START_RSP_EVT : AVDT_SCB_MSG_START_REJ_EVT;
311 /* get to where seid's are stashed in current cmd */
312 p = (UINT8 *)(p_ccb->p_curr_cmd + 1);
314 /* little trick here; length of current command equals number of streams */
315 for (i = 0; i < p_ccb->p_curr_cmd->len; i++)
317 if ((p_scb = avdt_scb_by_hdl(p[i])) != NULL)
319 avdt_scb_event(p_scb, event, (tAVDT_SCB_EVT *) &p_data->msg);
324 /*******************************************************************************
326 ** Function avdt_ccb_hdl_suspend_cmd
328 ** Description This function is called when a suspend command is received
329 ** from the peer. It verifies that all requested streams are
330 ** in the proper state. If so, it initiates sending of a
331 ** suspend response. Otherwise it sends a suspend reject.
337 *******************************************************************************/
338 void avdt_ccb_hdl_suspend_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
343 /* verify all streams in the right state */
344 if ((seid = avdt_scb_verify(p_ccb, AVDT_VERIFY_SUSPEND, p_data->msg.multi.seid_list,
345 p_data->msg.multi.num_seps, &err_code)) == 0 &&
348 /* we're ok, send response */
349 avdt_ccb_event(p_ccb, AVDT_CCB_API_SUSPEND_RSP_EVT, p_data);
353 /* not ok, send reject */
354 p_data->msg.hdr.err_code = err_code;
355 p_data->msg.hdr.err_param = seid;
356 avdt_msg_send_rej(p_ccb, AVDT_SIG_SUSPEND, &p_data->msg);
360 /*******************************************************************************
362 ** Function avdt_ccb_hdl_suspend_rsp
364 ** Description This function is called when a suspend response or reject
365 ** is received from the peer. Using the SEIDs stored in the
366 ** current command message, it sends a suspend response or
367 ** suspend reject event to each SCB associated with the command.
373 *******************************************************************************/
374 void avdt_ccb_hdl_suspend_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
381 /* determine rsp or rej event */
382 event = (p_data->msg.hdr.err_code == 0) ?
383 AVDT_SCB_MSG_SUSPEND_RSP_EVT : AVDT_SCB_MSG_SUSPEND_REJ_EVT;
385 /* get to where seid's are stashed in current cmd */
386 p = (UINT8 *)(p_ccb->p_curr_cmd + 1);
388 /* little trick here; length of current command equals number of streams */
389 for (i = 0; i < p_ccb->p_curr_cmd->len; i++)
391 if ((p_scb = avdt_scb_by_hdl(p[i])) != NULL)
393 avdt_scb_event(p_scb, event, (tAVDT_SCB_EVT *) &p_data->msg);
398 /*******************************************************************************
400 ** Function avdt_ccb_snd_discover_cmd
402 ** Description This function is called to send a discover command to the
403 ** peer. It copies variables needed for the procedure from
404 ** the event to the CCB. It marks the CCB as busy and then
405 ** sends a discover command.
410 *******************************************************************************/
411 void avdt_ccb_snd_discover_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
413 /* store info in ccb struct */
414 p_ccb->p_proc_data = p_data->discover.p_sep_info;
415 p_ccb->proc_cback = p_data->discover.p_cback;
416 p_ccb->proc_param = p_data->discover.num_seps;
419 p_ccb->proc_busy = TRUE;
421 /* build and queue discover req */
422 avdt_msg_send_cmd(p_ccb, NULL, AVDT_SIG_DISCOVER, NULL);
425 /*******************************************************************************
427 ** Function avdt_ccb_snd_discover_rsp
429 ** Description This function is called to send a discover response to
430 ** the peer. It takes the stream information passed in the
431 ** event and sends a discover response.
436 *******************************************************************************/
437 void avdt_ccb_snd_discover_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
440 avdt_msg_send_rsp(p_ccb, AVDT_SIG_DISCOVER, &p_data->msg);
443 /*******************************************************************************
445 ** Function avdt_ccb_snd_getcap_cmd
447 ** Description This function is called to send a get capabilities command
448 ** to the peer. It copies variables needed for the procedure
449 ** from the event to the CCB. It marks the CCB as busy and
450 ** then sends a get capabilities command.
455 *******************************************************************************/
456 void avdt_ccb_snd_getcap_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
458 UINT8 sig_id = AVDT_SIG_GETCAP;
460 /* store info in ccb struct */
461 p_ccb->p_proc_data = p_data->getcap.p_cfg;
462 p_ccb->proc_cback = p_data->getcap.p_cback;
465 p_ccb->proc_busy = TRUE;
467 /* build and queue discover req */
468 if (p_data->msg.hdr.sig_id == AVDT_SIG_GET_ALLCAP)
469 sig_id = AVDT_SIG_GET_ALLCAP;
471 avdt_msg_send_cmd(p_ccb, NULL, sig_id, (tAVDT_MSG *) &p_data->getcap.single);
474 /*******************************************************************************
476 ** Function avdt_ccb_snd_getcap_rsp
478 ** Description This function is called to send a get capabilities response
479 ** to the peer. It takes the stream information passed in the
480 ** event and sends a get capabilities response.
485 *******************************************************************************/
486 void avdt_ccb_snd_getcap_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
488 UINT8 sig_id = AVDT_SIG_GETCAP;
490 if (p_data->msg.hdr.sig_id == AVDT_SIG_GET_ALLCAP)
491 sig_id = AVDT_SIG_GET_ALLCAP;
494 avdt_msg_send_rsp(p_ccb, sig_id, &p_data->msg);
497 /*******************************************************************************
499 ** Function avdt_ccb_snd_start_cmd
501 ** Description This function is called to send a start command to the
502 ** peer. It verifies that all requested streams are in the
503 ** proper state. If so, it sends a start command. Otherwise
504 ** send ourselves back a start reject.
509 *******************************************************************************/
510 void avdt_ccb_snd_start_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
515 UINT8 seid_list[AVDT_NUM_SEPS];
517 /* make copy of our seid list */
518 memcpy(seid_list, p_data->msg.multi.seid_list, p_data->msg.multi.num_seps);
520 /* verify all streams in the right state */
521 if ((avdt_msg.hdr.err_param = avdt_scb_verify(p_ccb, AVDT_VERIFY_OPEN, p_data->msg.multi.seid_list,
522 p_data->msg.multi.num_seps, &avdt_msg.hdr.err_code)) == 0)
524 /* set peer seid list in messsage */
525 avdt_scb_peer_seid_list(&p_data->msg.multi);
528 avdt_msg_send_cmd(p_ccb, seid_list, AVDT_SIG_START, &p_data->msg);
532 /* failed; send ourselves a reject for each stream */
533 for (i = 0; i < p_data->msg.multi.num_seps; i++)
535 if ((p_scb = avdt_scb_by_hdl(seid_list[i])) != NULL)
537 avdt_scb_event(p_scb, AVDT_SCB_MSG_START_REJ_EVT, (tAVDT_SCB_EVT *) &avdt_msg.hdr);
543 /*******************************************************************************
545 ** Function avdt_ccb_snd_start_rsp
547 ** Description This function is called to send a start response to the
548 ** peer. It takes the stream information passed in the event
549 ** and sends a start response. Then it sends a start event
550 ** to the SCB for each stream.
555 *******************************************************************************/
556 void avdt_ccb_snd_start_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
561 /* send response message */
562 avdt_msg_send_rsp(p_ccb, AVDT_SIG_START, &p_data->msg);
564 /* send start event to each scb */
565 for (i = 0; i < p_data->msg.multi.num_seps; i++)
567 if ((p_scb = avdt_scb_by_hdl(p_data->msg.multi.seid_list[i])) != NULL)
569 avdt_scb_event(p_scb, AVDT_SCB_MSG_START_CMD_EVT, NULL);
574 /*******************************************************************************
576 ** Function avdt_ccb_snd_suspend_cmd
578 ** Description This function is called to send a suspend command to the
579 ** peer. It verifies that all requested streams are in the
580 ** proper state. If so, it sends a suspend command.
581 ** Otherwise it calls the callback function for each requested
582 ** stream and sends a suspend confirmation with failure.
587 *******************************************************************************/
588 void avdt_ccb_snd_suspend_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
593 UINT8 seid_list[AVDT_NUM_SEPS];
595 /* make copy of our seid list */
596 memcpy(seid_list, p_data->msg.multi.seid_list, p_data->msg.multi.num_seps);
598 /* verify all streams in the right state */
599 if ((avdt_msg.hdr.err_param = avdt_scb_verify(p_ccb, AVDT_VERIFY_STREAMING, p_data->msg.multi.seid_list,
600 p_data->msg.multi.num_seps, &avdt_msg.hdr.err_code)) == 0)
602 /* set peer seid list in messsage */
603 avdt_scb_peer_seid_list(&p_data->msg.multi);
606 avdt_msg_send_cmd(p_ccb, seid_list, AVDT_SIG_SUSPEND, &p_data->msg);
610 /* failed; send ourselves a reject for each stream */
611 for (i = 0; i < p_data->msg.multi.num_seps; i++)
613 if ((p_scb = avdt_scb_by_hdl(seid_list[i])) != NULL)
615 avdt_scb_event(p_scb, AVDT_SCB_MSG_SUSPEND_REJ_EVT, (tAVDT_SCB_EVT *) &avdt_msg.hdr);
621 /*******************************************************************************
623 ** Function avdt_ccb_snd_suspend_rsp
625 ** Description This function is called to send a suspend response to the
626 ** peer. It takes the stream information passed in the event
627 ** and sends a suspend response. Then it sends a suspend event
628 ** to the SCB for each stream.
633 *******************************************************************************/
634 void avdt_ccb_snd_suspend_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
639 /* send response message */
640 avdt_msg_send_rsp(p_ccb, AVDT_SIG_SUSPEND, &p_data->msg);
642 /* send start event to each scb */
643 for (i = 0; i < p_data->msg.multi.num_seps; i++)
645 if ((p_scb = avdt_scb_by_hdl(p_data->msg.multi.seid_list[i])) != NULL)
647 avdt_scb_event(p_scb, AVDT_SCB_MSG_SUSPEND_CMD_EVT, NULL);
652 /*******************************************************************************
654 ** Function avdt_ccb_clear_cmds
656 ** Description This function is called when the signaling channel is
657 ** closed to clean up any pending commands. For each pending
658 ** command in the command queue, it frees the command and
659 ** calls the application callback function indicating failure.
660 ** Certain CCB variables are also initialized.
665 *******************************************************************************/
666 void avdt_ccb_clear_cmds(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
669 tAVDT_SCB *p_scb = &avdt_cb.scb[0];
670 UINT8 err_code = AVDT_ERR_CONNECT;
674 avdt_ccb_clear_ccb(p_ccb);
676 /* clear out command queue; this is a little tricky here; we need
677 ** to handle the case where there is a command on deck in p_curr_cmd,
678 ** plus we need to clear out the queue
682 /* we know p_curr_cmd = NULL after this */
683 avdt_ccb_cmd_fail(p_ccb, (tAVDT_CCB_EVT *) &err_code);
685 /* set up next message */
686 p_ccb->p_curr_cmd = (BT_HDR *) fixed_queue_try_dequeue(p_ccb->cmd_q);
688 } while (p_ccb->p_curr_cmd != NULL);
690 /* send a CC_CLOSE_EVT any active scbs associated with this ccb */
691 for (i = 0; i < AVDT_NUM_SEPS; i++, p_scb++)
693 if ((p_scb->allocated) && (p_scb->p_ccb == p_ccb))
695 avdt_scb_event(p_scb, AVDT_SCB_CC_CLOSE_EVT, NULL);
700 /*******************************************************************************
702 ** Function avdt_ccb_cmd_fail
704 ** Description This function is called when there is a response timeout.
705 ** The currently pending command is freed and we fake a
706 ** reject message back to ourselves.
711 *******************************************************************************/
712 void avdt_ccb_cmd_fail(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
718 if (p_ccb->p_curr_cmd != NULL)
721 msg.hdr.err_code = p_data->err_code;
722 msg.hdr.err_param = 0;
723 msg.hdr.ccb_idx = avdt_ccb_to_idx(p_ccb);
725 /* pretend that we received a rej message */
726 evt = avdt_msg_rej_2_evt[p_ccb->p_curr_cmd->event - 1];
728 if (evt & AVDT_CCB_MKR)
730 avdt_ccb_event(p_ccb, (UINT8) (evt & ~AVDT_CCB_MKR), (tAVDT_CCB_EVT *) &msg);
734 /* we get the scb out of the current cmd */
735 p_scb = avdt_scb_by_hdl(*((UINT8 *)(p_ccb->p_curr_cmd + 1)));
738 avdt_scb_event(p_scb, evt, (tAVDT_SCB_EVT *) &msg);
742 osi_free_and_reset((void **)&p_ccb->p_curr_cmd);
746 /*******************************************************************************
748 ** Function avdt_ccb_free_cmd
750 ** Description This function is called when a response is received for a
751 ** currently pending command. The command is freed.
756 *******************************************************************************/
757 void avdt_ccb_free_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
760 osi_free_and_reset((void **)&p_ccb->p_curr_cmd);
763 /*******************************************************************************
765 ** Function avdt_ccb_cong_state
767 ** Description This function is called to set the congestion state for
773 *******************************************************************************/
774 void avdt_ccb_cong_state(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
776 p_ccb->cong = p_data->llcong;
779 /*******************************************************************************
781 ** Function avdt_ccb_ret_cmd
783 ** Description This function is called to retransmit the currently
784 ** pending command. The retransmission count is incremented.
785 ** If the count reaches the maximum number of retransmissions,
786 ** the event is treated as a response timeout.
791 *******************************************************************************/
792 void avdt_ccb_ret_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
794 UINT8 err_code = AVDT_ERR_TIMEOUT;
797 if (p_ccb->ret_count == AVDT_RET_MAX)
800 p_ccb->ret_count = 0;
801 avdt_ccb_cmd_fail(p_ccb, (tAVDT_CCB_EVT *) &err_code);
803 /* go to next queued command */
804 avdt_ccb_snd_cmd(p_ccb, p_data);
808 /* if command pending and we're not congested and not sending a fragment */
809 if ((!p_ccb->cong) && (p_ccb->p_curr_msg == NULL) && (p_ccb->p_curr_cmd != NULL))
811 /* make copy of message in p_curr_cmd and send it */
812 BT_HDR *p_msg = (BT_HDR *)osi_malloc(AVDT_CMD_BUF_SIZE);
813 memcpy(p_msg, p_ccb->p_curr_cmd,
814 (sizeof(BT_HDR) + p_ccb->p_curr_cmd->offset + p_ccb->p_curr_cmd->len));
815 avdt_msg_send(p_ccb, p_msg);
818 /* restart ret timer */
819 alarm_cancel(p_ccb->idle_ccb_timer);
820 alarm_cancel(p_ccb->rsp_ccb_timer);
821 period_ms_t interval_ms = avdt_cb.rcb.ret_tout * 1000;
822 alarm_set_on_queue(p_ccb->ret_ccb_timer, interval_ms,
823 avdt_ccb_ret_ccb_timer_timeout, p_ccb,
824 btu_general_alarm_queue);
828 /*******************************************************************************
830 ** Function avdt_ccb_snd_cmd
832 ** Description This function is called the send the next command,
833 ** if any, in the command queue.
838 *******************************************************************************/
839 void avdt_ccb_snd_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
844 /* do we have commands to send? send next command; make sure we're clear;
845 ** not congested, not sending fragment, not waiting for response
847 if ((!p_ccb->cong) && (p_ccb->p_curr_msg == NULL) && (p_ccb->p_curr_cmd == NULL))
849 if ((p_msg = (BT_HDR *) fixed_queue_try_dequeue(p_ccb->cmd_q)) != NULL)
851 /* make a copy of buffer in p_curr_cmd */
852 p_ccb->p_curr_cmd = (BT_HDR *)osi_malloc(AVDT_CMD_BUF_SIZE);
853 memcpy(p_ccb->p_curr_cmd, p_msg,
854 (sizeof(BT_HDR) + p_msg->offset + p_msg->len));
855 avdt_msg_send(p_ccb, p_msg);
860 /*******************************************************************************
862 ** Function avdt_ccb_snd_msg
869 *******************************************************************************/
870 void avdt_ccb_snd_msg(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
875 /* if not congested */
878 /* are we sending a fragmented message? continue sending fragment */
879 if (p_ccb->p_curr_msg != NULL)
881 avdt_msg_send(p_ccb, NULL);
883 /* do we have responses to send? send them */
884 else if (!fixed_queue_is_empty(p_ccb->rsp_q))
886 while ((p_msg = (BT_HDR *)fixed_queue_try_dequeue(p_ccb->rsp_q)) != NULL)
888 if (avdt_msg_send(p_ccb, p_msg) == TRUE)
890 /* break out if congested */
896 /* do we have commands to send? send next command */
897 avdt_ccb_snd_cmd(p_ccb, NULL);
901 /*******************************************************************************
903 ** Function avdt_ccb_set_reconn
905 ** Description This function is called to enable a reconnect attempt when
906 ** a channel transitions from closing to idle state. It sets
907 ** the reconn variable to TRUE.
912 *******************************************************************************/
913 void avdt_ccb_set_reconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
917 p_ccb->reconn = TRUE;
920 /*******************************************************************************
922 ** Function avdt_ccb_clr_reconn
924 ** Description This function is called to clear the reconn variable.
929 *******************************************************************************/
930 void avdt_ccb_clr_reconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
934 p_ccb->reconn = FALSE;
937 /*******************************************************************************
939 ** Function avdt_ccb_chk_reconn
941 ** Description This function is called to check if a reconnect attempt
942 ** is enabled. If enabled, it sends an AVDT_CCB_UL_OPEN_EVT
943 ** to the CCB. If disabled, the CCB is deallocated.
948 *******************************************************************************/
949 void avdt_ccb_chk_reconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
951 UINT8 err_code = AVDT_ERR_CONNECT;
956 p_ccb->reconn = FALSE;
959 avdt_ccb_clear_ccb(p_ccb);
961 /* clear out current command, if any */
962 avdt_ccb_cmd_fail(p_ccb, (tAVDT_CCB_EVT *) &err_code);
964 /* reopen the signaling channel */
965 avdt_ccb_event(p_ccb, AVDT_CCB_UL_OPEN_EVT, NULL);
969 avdt_ccb_ll_closed(p_ccb, NULL);
973 /*******************************************************************************
975 ** Function avdt_ccb_chk_timer
977 ** Description This function stops the CCB timer if the idle timer is
983 *******************************************************************************/
984 void avdt_ccb_chk_timer(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
988 alarm_cancel(p_ccb->idle_ccb_timer);
991 /*******************************************************************************
993 ** Function avdt_ccb_set_conn
995 ** Description Set CCB variables associated with AVDT_ConnectReq().
1000 *******************************************************************************/
1001 void avdt_ccb_set_conn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
1004 p_ccb->p_conn_cback = p_data->connect.p_cback;
1006 /* set security level */
1007 BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_AVDTP, p_data->connect.sec_mask,
1008 AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_SIG);
1011 /*******************************************************************************
1013 ** Function avdt_ccb_set_disconn
1015 ** Description Set CCB variables associated with AVDT_DisconnectReq().
1020 *******************************************************************************/
1021 void avdt_ccb_set_disconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
1024 AVDT_TRACE_EVENT("avdt_ccb_set_disconn:conn:x%x, api:x%x",
1025 p_ccb->p_conn_cback, p_data->disconnect.p_cback);
1028 if (p_data->disconnect.p_cback)
1029 p_ccb->p_conn_cback = p_data->disconnect.p_cback;
1032 /*******************************************************************************
1034 ** Function avdt_ccb_do_disconn
1036 ** Description Do action associated with AVDT_DisconnectReq().
1041 *******************************************************************************/
1042 void avdt_ccb_do_disconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
1046 /* clear any pending commands */
1047 avdt_ccb_clear_cmds(p_ccb, NULL);
1050 avdt_ccb_chan_close(p_ccb, NULL);
1053 /*******************************************************************************
1055 ** Function avdt_ccb_ll_closed
1057 ** Description Clear commands from and deallocate CCB.
1062 *******************************************************************************/
1063 void avdt_ccb_ll_closed(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
1065 tAVDT_CTRL_CBACK *p_cback;
1067 tAVDT_CTRL avdt_ctrl;
1070 /* clear any pending commands */
1071 avdt_ccb_clear_cmds(p_ccb, NULL);
1073 /* save callback pointer, bd addr */
1074 p_cback = p_ccb->p_conn_cback;
1076 p_cback = avdt_cb.p_conn_cback;
1077 memcpy(bd_addr, p_ccb->peer_addr, BD_ADDR_LEN);
1080 avdt_ccb_dealloc(p_ccb, NULL);
1085 avdt_ctrl.hdr.err_code = 0;
1086 (*p_cback)(0, bd_addr, AVDT_DISCONNECT_IND_EVT, &avdt_ctrl);
1090 /*******************************************************************************
1092 ** Function avdt_ccb_ll_opened
1094 ** Description Call callback on open.
1099 *******************************************************************************/
1100 void avdt_ccb_ll_opened(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
1102 tAVDT_CTRL avdt_ctrl;
1104 p_ccb->ll_opened = TRUE;
1106 if (!p_ccb->p_conn_cback)
1107 p_ccb->p_conn_cback = avdt_cb.p_conn_cback;
1110 if (p_ccb->p_conn_cback)
1112 avdt_ctrl.hdr.err_code = 0;
1113 avdt_ctrl.hdr.err_param = p_data->msg.hdr.err_param;
1114 (*p_ccb->p_conn_cback)(0, p_ccb->peer_addr, AVDT_CONNECT_IND_EVT, &avdt_ctrl);