*******************************************************************************/
void bta_av_dup_audio_buf(tBTA_AV_SCB *p_scb, BT_HDR *p_buf)
{
- tBTA_AV_SCB *p_scbi;
- int i;
- UINT16 size, copy_size;
- BT_HDR *p_new;
-
- if(!p_buf)
+ /* Test whether there is more than one audio channel connected */
+ if ((p_buf == NULL) || (bta_av_cb.audio_open_cnt < 2))
return;
- if(bta_av_cb.audio_open_cnt >= 2)
- {
- size = osi_get_buf_size(p_buf);
- copy_size = BT_HDR_SIZE + p_buf->len + p_buf->offset;
- /* more than one audio channel is connected */
- for(i=0; i<BTA_AV_NUM_STRS; i++)
- {
- p_scbi = bta_av_cb.p_scb[i];
- if( (p_scb->hdi != i) && /* not the original channel */
- (bta_av_cb.conn_audio & BTA_AV_HNDL_TO_MSK(i)) && /* connected audio */
- p_scbi && p_scbi->co_started ) /* scb is used and started */
- {
- /* enqueue the data only when the stream is started */
- p_new = (BT_HDR *)osi_getbuf(size);
- if(p_new)
- {
- memcpy(p_new, p_buf, copy_size);
- list_append(p_scbi->a2d_list, p_new);
- if (list_length(p_scbi->a2d_list) > p_bta_av_cfg->audio_mqs) {
- // Drop the oldest packet
- bta_av_co_audio_drop(p_scbi->hndl);
- BT_HDR *p_buf = list_front(p_scbi->a2d_list);
- list_remove(p_scbi->a2d_list, p_buf);
- osi_freebuf(p_buf);
- }
- }
- }
+ UINT16 copy_size = BT_HDR_SIZE + p_buf->len + p_buf->offset;
+ for (int i = 0; i < BTA_AV_NUM_STRS; i++) {
+ tBTA_AV_SCB *p_scbi = bta_av_cb.p_scb[i];
+
+ if (i == p_scb->hdi)
+ continue; /* Ignore the original channel */
+ if ((p_scbi == NULL) || !p_scbi->co_started)
+ continue; /* Ignore if SCB is not used or started */
+ if (!(bta_av_cb.conn_audio & BTA_AV_HNDL_TO_MSK(i)))
+ continue; /* Audio is not connected */
+
+ /* Enqueue the data */
+ BT_HDR *p_new = (BT_HDR *)osi_getbuf(copy_size);
+ memcpy(p_new, p_buf, copy_size);
+ list_append(p_scbi->a2d_list, p_new);
+
+ if (list_length(p_scbi->a2d_list) > p_bta_av_cfg->audio_mqs) {
+ // Drop the oldest packet
+ bta_av_co_audio_drop(p_scbi->hndl);
+ BT_HDR *p_buf_drop = list_front(p_scbi->a2d_list);
+ list_remove(p_scbi->a2d_list, p_buf_drop);
+ osi_freebuf(p_buf_drop);
}
}
-
}
/*******************************************************************************
void osi_free_and_reset(void **p_ptr);
//
-// TODO: Function osi_get_buf_size() should be removed.
-// The rest of the functions below should be removed and replaced with the
+// TODO: The functions below should be removed and replaced with the
// corresponding functions above.
//
// |p_ptr| is a pointer to the buffer pointer to be reset.
// |p_ptr| cannot be NULL.
void osi_freebuf_and_reset(void **p_ptr);
-
-// Get the size of the buffer previously allocated with function |osi_getbuf|
-uint16_t osi_get_buf_size(void *ptr);
osi_freebuf(*p_ptr);
*p_ptr = NULL;
}
-
-uint16_t osi_get_buf_size(void *p_buf)
-{
- BUFFER_HDR_T *header = (BUFFER_HDR_T *)p_buf - 1;
- assert(header->magic_number == MAGIC_NUMBER);
- return header->size;
-}
UINT8 *p;
UINT8 pkt_type;
BT_HDR *p_ret;
- UINT16 buf_len;
/* parse the message header */
p = (UINT8 *)(p_buf + 1) + p_buf->offset;
{
/* if reassembly in progress drop message and process new single */
if (p_lcb->p_rx_msg != NULL)
- {
AVCT_TRACE_WARNING("Got single during reassembly");
- osi_freebuf_and_reset((void **)&p_lcb->p_rx_msg);
- }
+
+ osi_freebuf_and_reset((void **)&p_lcb->p_rx_msg);
+
p_ret = p_buf;
}
/* start packet */
osi_freebuf(p_lcb->p_rx_msg);
- /* Allocate bigger buffer for reassembly. As lower layers are
- * not aware of possible packet size after reassembly they
+ /*
+ * Allocate bigger buffer for reassembly. As lower layers are
+ * not aware of possible packet size after reassembly, they
* would have allocated smaller buffer.
*/
- p_lcb->p_rx_msg = (BT_HDR*)osi_getbuf(BT_DEFAULT_BUFFER_SIZE);
- if (p_lcb->p_rx_msg == NULL)
- {
- AVCT_TRACE_ERROR ("Cannot alloc buffer for reassembly !!");
- osi_freebuf(p_buf);
- }
- else
- {
- memcpy (p_lcb->p_rx_msg, p_buf,
- sizeof(BT_HDR) + p_buf->offset + p_buf->len);
- /* Free original buffer */
- osi_freebuf(p_buf);
+ p_lcb->p_rx_msg = (BT_HDR *)osi_getbuf(BT_DEFAULT_BUFFER_SIZE);
+ memcpy(p_lcb->p_rx_msg, p_buf,
+ sizeof(BT_HDR) + p_buf->offset + p_buf->len);
- /* update p to point to new buffer */
- p = (UINT8 *)(p_lcb->p_rx_msg + 1) + p_lcb->p_rx_msg->offset;
+ /* Free original buffer */
+ osi_freebuf(p_buf);
- /* copy first header byte over nosp */
- *(p + 1) = *p;
+ /* update p to point to new buffer */
+ p = (UINT8 *)(p_lcb->p_rx_msg + 1) + p_lcb->p_rx_msg->offset;
- /* set offset to point to where to copy next */
- p_lcb->p_rx_msg->offset += p_lcb->p_rx_msg->len;
+ /* copy first header byte over nosp */
+ *(p + 1) = *p;
+
+ /* set offset to point to where to copy next */
+ p_lcb->p_rx_msg->offset += p_lcb->p_rx_msg->len;
+
+ /* adjust length for packet header */
+ p_lcb->p_rx_msg->len -= 1;
- /* adjust length for packet header */
- p_lcb->p_rx_msg->len -= 1;
- }
p_ret = NULL;
}
/* continue or end */
else
{
/* get size of buffer holding assembled message */
- buf_len = osi_get_buf_size(p_lcb->p_rx_msg) - sizeof(BT_HDR);
+ /*
+ * NOTE: The buffer is allocated above at the beginning of the
+ * reassembly, and is always of size BT_DEFAULT_BUFFER_SIZE.
+ */
+ UINT16 buf_len = BT_DEFAULT_BUFFER_SIZE - sizeof(BT_HDR);
/* adjust offset and len of fragment for header byte */
p_buf->offset += AVCT_HDR_LEN_CONT;
p_buf->len -= AVCT_HDR_LEN_CONT;
/* verify length */
- if ((p_lcb->p_rx_msg->offset + p_buf->len) > buf_len)
- {
+ if ((p_lcb->p_rx_msg->offset + p_buf->len) > buf_len) {
/* won't fit; free everything */
+ AVCT_TRACE_WARNING("%s: Fragmented message too big!", __func__);
osi_freebuf_and_reset((void **)&p_lcb->p_rx_msg);
osi_freebuf(p_buf);
p_ret = NULL;
- AVCT_TRACE_WARNING("Fragmented message too big!");
- }
- else
- {
+ } else {
/* copy contents of p_buf to p_rx_msg */
memcpy((UINT8 *)(p_lcb->p_rx_msg + 1) + p_lcb->p_rx_msg->offset,
(UINT8 *)(p_buf + 1) + p_buf->offset, p_buf->len);
UINT8 *p;
UINT8 pkt_type;
BT_HDR *p_ret;
- UINT16 buf_len;
/* parse the message header */
p = (UINT8 *)(p_buf + 1) + p_buf->offset;
AVDT_TRACE_WARNING("Got start during reassembly");
osi_freebuf_and_reset((void **)&p_ccb->p_rx_msg);
- p_ccb->p_rx_msg = p_buf;
+
+ /*
+ * Allocate bigger buffer for reassembly. As lower layers are
+ * not aware of possible packet size after reassembly, they
+ * would have allocated smaller buffer.
+ */
+ p_ccb->p_rx_msg = (BT_HDR *)osi_getbuf(BT_DEFAULT_BUFFER_SIZE);
+ memcpy(p_ccb->p_rx_msg, p_buf,
+ sizeof(BT_HDR) + p_buf->offset + p_buf->len);
+
+ /* Free original buffer */
+ osi_freebuf(p_buf);
+
+ /* update p to point to new buffer */
+ p = (UINT8 *)(p_ccb->p_rx_msg + 1) + p_ccb->p_rx_msg->offset;
/* copy first header byte over nosp */
*(p + 1) = *p;
else
{
/* get size of buffer holding assembled message */
- buf_len = osi_get_buf_size(p_ccb->p_rx_msg) - sizeof(BT_HDR);
+ /*
+ * NOTE: The buffer is allocated above at the beginning of the
+ * reassembly, and is always of size BT_DEFAULT_BUFFER_SIZE.
+ */
+ UINT16 buf_len = BT_DEFAULT_BUFFER_SIZE - sizeof(BT_HDR);
/* adjust offset and len of fragment for header byte */
p_buf->offset += AVDT_LEN_TYPE_CONT;
p_buf->len -= AVDT_LEN_TYPE_CONT;
/* verify length */
- if ((p_ccb->p_rx_msg->offset + p_buf->len) > buf_len)
- {
+ if ((p_ccb->p_rx_msg->offset + p_buf->len) > buf_len) {
/* won't fit; free everything */
+ AVDT_TRACE_WARNING("%s: Fragmented message too big!", __func__);
osi_freebuf_and_reset((void **)&p_ccb->p_rx_msg);
osi_freebuf(p_buf);
p_ret = NULL;
- }
- else
- {
+ } else {
/* copy contents of p_buf to p_rx_msg */
memcpy((UINT8 *)(p_ccb->p_rx_msg + 1) + p_ccb->p_rx_msg->offset,
(UINT8 *)(p_buf + 1) + p_buf->offset, p_buf->len);
BOOLEAN req_continue = FALSE;
BT_HDR *p_pkt_new = NULL;
UINT8 pkt_type;
- UINT16 buf_len;
tAVRC_RASM_CB *p_rcb;
tAVRC_NEXT_CMD avrc_cmd;
if (pkt_type != AVRC_PKT_SINGLE && cr == AVCT_RSP)
{
/* not a single response packet - need to re-assemble metadata messages */
- if (pkt_type == AVRC_PKT_START)
- {
+ if (pkt_type == AVRC_PKT_START) {
/* Allocate buffer for re-assembly */
p_rcb->rasm_pdu = *p_data;
- if ((p_rcb->p_rmsg = (BT_HDR *)osi_getbuf(BT_DEFAULT_BUFFER_SIZE)) != NULL)
- {
- /* Copy START packet to buffer for re-assembling fragments*/
- memcpy(p_rcb->p_rmsg, p_pkt, sizeof(BT_HDR)); /* Copy bt hdr */
+ p_rcb->p_rmsg = (BT_HDR *)osi_getbuf(BT_DEFAULT_BUFFER_SIZE);
+ /* Copy START packet to buffer for re-assembling fragments */
+ memcpy(p_rcb->p_rmsg, p_pkt, sizeof(BT_HDR)); /* Copy bt hdr */
- /* Copy metadata message */
- memcpy((UINT8 *)(p_rcb->p_rmsg + 1),
- (UINT8 *)(p_pkt+1) + p_pkt->offset, p_pkt->len);
+ /* Copy metadata message */
+ memcpy((UINT8 *)(p_rcb->p_rmsg + 1),
+ (UINT8 *)(p_pkt+1) + p_pkt->offset, p_pkt->len);
- /* offset of start of metadata response in reassembly buffer */
- p_rcb->p_rmsg->offset = p_rcb->rasm_offset = 0;
+ /* offset of start of metadata response in reassembly buffer */
+ p_rcb->p_rmsg->offset = p_rcb->rasm_offset = 0;
- /* Free original START packet, replace with pointer to reassembly buffer */
- osi_freebuf(p_pkt);
- *pp_pkt = p_rcb->p_rmsg;
- }
- else
- {
- /* Unable to allocate buffer for fragmented avrc message. Reuse START
- buffer for reassembly (re-assembled message may fit into ACL buf) */
- AVRC_TRACE_DEBUG ("Unable to allocate buffer for fragmented avrc message, \
- reusing START buffer for reassembly");
- p_rcb->rasm_offset = p_pkt->offset;
- p_rcb->p_rmsg = p_pkt;
- }
+ /*
+ * Free original START packet, replace with pointer to
+ * reassembly buffer.
+ */
+ osi_freebuf(p_pkt);
+ *pp_pkt = p_rcb->p_rmsg;
- /* set offset to point to where to copy next - use the same re-asm logic as AVCT */
+ /*
+ * Set offset to point to where to copy next - use the same
+ * reassembly logic as AVCT.
+ */
p_rcb->p_rmsg->offset += p_rcb->p_rmsg->len;
req_continue = TRUE;
- }
- else if (p_rcb->p_rmsg == NULL)
- {
+ } else if (p_rcb->p_rmsg == NULL) {
/* Received a CONTINUE/END, but no corresponding START
(or previous fragmented response was dropped) */
AVRC_TRACE_DEBUG ("Received a CONTINUE/END without no corresponding START \
else
{
/* get size of buffer holding assembled message */
- buf_len = osi_get_buf_size (p_rcb->p_rmsg) - sizeof(BT_HDR);
+ /*
+ * NOTE: The buffer is allocated above at the beginning of the
+ * reassembly, and is always of size BT_DEFAULT_BUFFER_SIZE.
+ */
+ UINT16 buf_len = BT_DEFAULT_BUFFER_SIZE - sizeof(BT_HDR);
/* adjust offset and len of fragment for header byte */
p_pkt->offset += (AVRC_VENDOR_HDR_SIZE + AVRC_MIN_META_HDR_SIZE);
p_pkt->len -= (AVRC_VENDOR_HDR_SIZE + AVRC_MIN_META_HDR_SIZE);
/* get the existing length, if any, and also the num attributes */
p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
p_data = p_len = p_start + 2; /* pdu + rsvd */
- len_left = osi_get_buf_size(p_pkt) - BT_HDR_SIZE - p_pkt->offset - p_pkt->len;
+
+ /*
+ * NOTE: The buffer is allocated within avrc_bld_init_rsp_buffer(), and is
+ * always of size BT_DEFAULT_BUFFER_SIZE.
+ */
+ len_left = BT_DEFAULT_BUFFER_SIZE - BT_HDR_SIZE - p_pkt->offset - p_pkt->len;
BE_STREAM_TO_UINT16(len, p_data);
p_count = p_data;
{
UINT16 offset = AVRC_MSG_PASS_THRU_OFFSET;
UINT16 chnl = AVCT_DATA_CTRL;
- UINT16 len = AVRC_META_CMD_BUF_SIZE;
BT_HDR *p_pkt = NULL;
UINT8 opcode = avrc_opcode_from_pdu(p_rsp->pdu);
case AVRC_OP_VENDOR:
offset = AVRC_MSG_VENDOR_OFFSET;
- if (p_rsp->pdu == AVRC_PDU_GET_ELEMENT_ATTR)
- len = AVRC_BROWSE_BUF_SIZE;
break;
}
/* allocate and initialize the buffer */
- p_pkt = (BT_HDR *)osi_getbuf(len);
+ p_pkt = (BT_HDR *)osi_getbuf(BT_DEFAULT_BUFFER_SIZE);
if (p_pkt)
{
UINT8 *p_data, *p_start;
return;
}
- /* Check if this is a continuation request */
- if (*p_req)
- {
- /* Free and reallocate buffer */
- osi_freebuf(p_ccb->rsp_list);
- p_ccb->rsp_list = (UINT8 *)osi_getbuf(max_list_len);
- if (*p_req++ != SDP_CONTINUATION_LEN)
- {
- sdpu_build_n_send_error (p_ccb, trans_num, SDP_INVALID_CONT_STATE, SDP_TEXT_BAD_CONT_LEN);
- return;
- }
- BE_STREAM_TO_UINT16 (cont_offset, p_req);
+ /* Free and reallocate buffer */
+ osi_freebuf(p_ccb->rsp_list);
+ p_ccb->rsp_list = (UINT8 *)osi_getbuf(max_list_len);
- if (cont_offset != p_ccb->cont_offset)
- {
- sdpu_build_n_send_error (p_ccb, trans_num, SDP_INVALID_CONT_STATE, SDP_TEXT_BAD_CONT_INX);
+ /* Check if this is a continuation request */
+ if (*p_req) {
+ if (*p_req++ != SDP_CONTINUATION_LEN) {
+ sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
+ SDP_TEXT_BAD_CONT_LEN);
return;
}
+ BE_STREAM_TO_UINT16(cont_offset, p_req);
- if (!p_ccb->rsp_list)
- {
- sdpu_build_n_send_error (p_ccb, trans_num, SDP_NO_RESOURCES, NULL);
+ if (cont_offset != p_ccb->cont_offset) {
+ sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
+ SDP_TEXT_BAD_CONT_INX);
return;
}
is_cont = TRUE;
/* Initialise for continuation response */
p_rsp = &p_ccb->rsp_list[0];
- attr_seq.attr_entry[p_ccb->cont_info.next_attr_index].start = p_ccb->cont_info.next_attr_start_id;
- }
- else
- {
- /* Get a scratch buffer to store response */
- if (!p_ccb->rsp_list || (osi_get_buf_size(p_ccb->rsp_list) < max_list_len))
- {
- /* Free and reallocate if the earlier allocated buffer is small */
- osi_freebuf(p_ccb->rsp_list);
- p_ccb->rsp_list = (UINT8 *)osi_getbuf (max_list_len);
- if (p_ccb->rsp_list == NULL)
- {
- SDP_TRACE_ERROR ("SDP - no scratch buf for search rsp");
- return;
- }
- }
-
+ attr_seq.attr_entry[p_ccb->cont_info.next_attr_index].start =
+ p_ccb->cont_info.next_attr_start_id;
+ } else {
p_ccb->cont_offset = 0;
- p_rsp = &p_ccb->rsp_list[3]; /* Leave space for data elem descr */
+ p_rsp = &p_ccb->rsp_list[3]; /* Leave space for data elem descr */
/* Reset continuation parameters in p_ccb */
p_ccb->cont_info.prev_sdp_rec = NULL;
memcpy(&attr_seq_sav, &attr_seq, sizeof(tSDP_ATTR_SEQ)) ;
- /* Check if this is a continuation request */
- if (*p_req)
- {
- /* Free and reallocate buffer */
- osi_freebuf(p_ccb->rsp_list);
- p_ccb->rsp_list = (UINT8 *)osi_getbuf (max_list_len);
- if (p_ccb->rsp_list == NULL)
- {
- SDP_TRACE_ERROR ("SDP - no scratch buf for search rsp");
- return;
- }
-
- if (*p_req++ != SDP_CONTINUATION_LEN)
- {
- sdpu_build_n_send_error (p_ccb, trans_num, SDP_INVALID_CONT_STATE, SDP_TEXT_BAD_CONT_LEN);
- return;
- }
- BE_STREAM_TO_UINT16 (cont_offset, p_req);
+ /* Free and reallocate buffer */
+ osi_freebuf(p_ccb->rsp_list);
+ p_ccb->rsp_list = (UINT8 *)osi_getbuf(max_list_len);
- if (cont_offset != p_ccb->cont_offset)
- {
- sdpu_build_n_send_error (p_ccb, trans_num, SDP_INVALID_CONT_STATE, SDP_TEXT_BAD_CONT_INX);
+ /* Check if this is a continuation request */
+ if (*p_req) {
+ if (*p_req++ != SDP_CONTINUATION_LEN) {
+ sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
+ SDP_TEXT_BAD_CONT_LEN);
return;
}
+ BE_STREAM_TO_UINT16(cont_offset, p_req);
- if (!p_ccb->rsp_list)
- {
- sdpu_build_n_send_error (p_ccb, trans_num, SDP_NO_RESOURCES, NULL);
+ if (cont_offset != p_ccb->cont_offset) {
+ sdpu_build_n_send_error (p_ccb, trans_num, SDP_INVALID_CONT_STATE,
+ SDP_TEXT_BAD_CONT_INX);
return;
}
is_cont = TRUE;
/* Initialise for continuation response */
p_rsp = &p_ccb->rsp_list[0];
- attr_seq.attr_entry[p_ccb->cont_info.next_attr_index].start = p_ccb->cont_info.next_attr_start_id;
- }
- else
- {
- /* Get a scratch buffer to store response */
- if (!p_ccb->rsp_list || (osi_get_buf_size(p_ccb->rsp_list) < max_list_len))
- {
- /* Free and reallocate if the earlier allocated buffer is small */
- osi_freebuf(p_ccb->rsp_list);
- p_ccb->rsp_list = (UINT8 *)osi_getbuf (max_list_len);
- if (p_ccb->rsp_list == NULL)
- {
- SDP_TRACE_ERROR ("SDP - no scratch buf for search rsp");
- return;
- }
- }
-
+ attr_seq.attr_entry[p_ccb->cont_info.next_attr_index].start =
+ p_ccb->cont_info.next_attr_start_id;
+ } else {
p_ccb->cont_offset = 0;
- p_rsp = &p_ccb->rsp_list[3]; /* Leave space for data elem descr */
+ p_rsp = &p_ccb->rsp_list[3]; /* Leave space for data elem descr */
/* Reset continuation parameters in p_ccb */
p_ccb->cont_info.prev_sdp_rec = NULL;