/****************************************************************************** ** ** Function avrc_send_continue_frag ** ** Description This function sends a continue response fragment ** ** Returns Nothing. ** ******************************************************************************/ static void avrc_send_continue_frag(UINT8 handle, UINT8 label) { tAVRC_FRAG_CB *p_fcb; BT_HDR *p_pkt_old, *p_pkt; UINT8 *p_old, *p_data; UINT8 cr = AVCT_RSP; tAVRC_RSP rej_rsp; p_fcb = &avrc_cb.fcb[handle]; p_pkt = p_fcb->p_fmsg; AVRC_TRACE_DEBUG("%s handle = %u label = %u len = %d", __func__, handle, label, p_pkt->len); if (p_pkt->len > AVRC_MAX_CTRL_DATA_LEN) { int offset_len = MAX(AVCT_MSG_OFFSET, p_pkt->offset); p_pkt_old = p_fcb->p_fmsg; p_pkt = (BT_HDR *)osi_malloc((UINT16)(AVRC_PACKET_LEN + offset_len + BT_HDR_SIZE)); if (p_pkt) { p_pkt->len = AVRC_MAX_CTRL_DATA_LEN; p_pkt->offset = AVCT_MSG_OFFSET; p_pkt->layer_specific = p_pkt_old->layer_specific; p_pkt->event = p_pkt_old->event; p_old = (UINT8 *)(p_pkt_old + 1) + p_pkt_old->offset; p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset; memcpy (p_data, p_old, AVRC_MAX_CTRL_DATA_LEN); /* use AVRC continue packet type */ p_data += AVRC_VENDOR_HDR_SIZE; p_data++; /* pdu */ *p_data++ = AVRC_PKT_CONTINUE; /* 4=pdu, pkt_type & len */ UINT16_TO_BE_STREAM(p_data, (AVRC_MAX_CTRL_DATA_LEN - AVRC_VENDOR_HDR_SIZE - 4)); /* prepare the left over for as an end fragment */ avrc_prep_end_frag (handle); } else { /* use the current GKI buffer to send Internal error status */ p_pkt = p_fcb->p_fmsg; p_fcb->p_fmsg = NULL; p_fcb->frag_enabled = FALSE; AVRC_TRACE_ERROR ("AVRC_MsgReq no buffers for fragmentation - send internal error" ); p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset; *p_data++ = AVRC_PDU_REQUEST_CONTINUATION_RSP; *p_data++ = 0; UINT16_TO_BE_STREAM(p_data, 0); p_pkt->len = 4; rej_rsp.pdu = AVRC_PDU_REQUEST_CONTINUATION_RSP; rej_rsp.status = AVRC_STS_INTERNAL_ERR; AVRC_BldResponse( handle, (tAVRC_RESPONSE *)&rej_rsp, &p_pkt); cr = AVCT_RSP; } } else { /* end fragment. clean the control block */ p_fcb->frag_enabled = FALSE; p_fcb->p_fmsg = NULL; } AVCT_MsgReq( handle, label, cr, p_pkt); }
/* Generic reject response */ static void send_reject_response (UINT8 rc_handle, UINT8 label, UINT8 pdu, UINT8 status) { UINT8 ctype = AVRC_RSP_REJ; tAVRC_RESPONSE avrc_rsp; BT_HDR *p_msg = NULL; memset (&avrc_rsp, 0, sizeof(tAVRC_RESPONSE)); avrc_rsp.rsp.opcode = opcode_from_pdu(pdu); avrc_rsp.rsp.pdu = pdu; avrc_rsp.rsp.status = status; if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse(rc_handle, &avrc_rsp, &p_msg)) ) { BTIF_TRACE_DEBUG4("%s:Sending error notification to handle:%d. pdu:%s,status:0x%02x", __FUNCTION__, rc_handle, dump_rc_pdu(pdu), status); BTA_AvMetaRsp(rc_handle, label, ctype, p_msg); } }
/*************************************************************************** * Function send_metamsg_rsp * * - Argument: * rc_handle RC handle corresponding to the connected RC * label Label of the RC response * code Response type * pmetamsg_resp Vendor response * * - Description: Remote control metamsg response handler (AVRCP 1.3) * ***************************************************************************/ static void send_metamsg_rsp (UINT8 rc_handle, UINT8 label, tBTA_AV_CODE code, tAVRC_RESPONSE *pmetamsg_resp) { UINT8 ctype; tAVRC_STS status; if (!pmetamsg_resp) { BTIF_TRACE_WARNING1("%s: Invalid response received from application", __FUNCTION__); return; } BTIF_TRACE_EVENT5("+%s: rc_handle: %d, label: %d, code: 0x%02x, pdu: %s", __FUNCTION__, rc_handle, label, code, dump_rc_pdu(pmetamsg_resp->rsp.pdu)); if (pmetamsg_resp->rsp.status != AVRC_STS_NO_ERROR) { ctype = AVRC_RSP_REJ; } else { if ( code < AVRC_RSP_NOT_IMPL) { if (code == AVRC_CMD_NOTIF) { ctype = AVRC_RSP_INTERIM; } else if (code == AVRC_CMD_STATUS) { ctype = AVRC_RSP_IMPL_STBL; } else { ctype = AVRC_RSP_ACCEPT; } } else { ctype = code; } } /* if response is for register_notification, make sure the rc has actually registered for this */ if((pmetamsg_resp->rsp.pdu == AVRC_PDU_REGISTER_NOTIFICATION) && (code == AVRC_RSP_CHANGED)) { BOOLEAN bSent = FALSE; UINT8 event_id = pmetamsg_resp->reg_notif.event_id; BOOLEAN bNotify = (btif_rc_cb.rc_connected) && (btif_rc_cb.rc_notif[event_id-1].bNotify); /* de-register this notification for a CHANGED response */ btif_rc_cb.rc_notif[event_id-1].bNotify = FALSE; BTIF_TRACE_DEBUG4("%s rc_handle: %d. event_id: 0x%02d bNotify:%u", __FUNCTION__, btif_rc_cb.rc_handle, event_id, bNotify); if (bNotify) { BT_HDR *p_msg = NULL; tAVRC_STS status; if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse(btif_rc_cb.rc_handle, pmetamsg_resp, &p_msg)) ) { BTIF_TRACE_DEBUG3("%s Sending notification to rc_handle: %d. event_id: 0x%02d", __FUNCTION__, btif_rc_cb.rc_handle, event_id); bSent = TRUE; BTA_AvMetaRsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_notif[event_id-1].label, ctype, p_msg); } else { BTIF_TRACE_WARNING2("%s failed to build metamsg response. status: 0x%02x", __FUNCTION__, status); } } if (!bSent) { BTIF_TRACE_DEBUG2("%s: Notification not sent, as there are no RC connections or the \ CT has not subscribed for event_id: %s", __FUNCTION__, dump_rc_notification_event_id(event_id)); }