/******************************************************************************* ** ** Function rw_t2t_select ** ** Description This function selects type 2 tag. ** ** Returns Tag selection status ** *******************************************************************************/ tNFC_STATUS rw_t2t_select (void) { tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; p_t2t->state = RW_T2T_STATE_IDLE; p_t2t->ndef_status = T2T_NDEF_NOT_DETECTED; /* Alloc cmd buf for retransmissions */ if (p_t2t->p_cur_cmd_buf == NULL) { if ((p_t2t->p_cur_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) == NULL) { RW_TRACE_ERROR0 ("rw_t2t_select: unable to allocate buffer for retransmission"); return (NFC_STATUS_FAILED); } } /* Alloc cmd buf for holding a command untill sector changes */ if (p_t2t->p_sec_cmd_buf == NULL) { if ((p_t2t->p_sec_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) == NULL) { RW_TRACE_ERROR0 ("rw_t2t_select: unable to allocate buffer used during sector change"); return (NFC_STATUS_FAILED); } } NFC_SetStaticRfCback (rw_t2t_conn_cback); rw_t2t_handle_op_complete (); p_t2t->check_tag_halt = FALSE; return NFC_STATUS_OK; }
/****************************************************************************** ** ** Function avrc_vendor_msg ** ** Description Compose a VENDOR DEPENDENT command according to p_msg ** ** Input Parameters: ** p_msg: Pointer to VENDOR DEPENDENT message structure. ** ** Output Parameters: ** None. ** ** Returns pointer to a valid GKI buffer if successful. ** NULL if p_msg is NULL. ** ******************************************************************************/ static BT_HDR *avrc_vendor_msg(tAVRC_MSG_VENDOR *p_msg) { BT_HDR *p_cmd; UINT8 *p_data; assert(p_msg != NULL); #if AVRC_METADATA_INCLUDED == TRUE assert(AVRC_META_CMD_POOL_SIZE > (AVRC_MIN_CMD_LEN + p_msg->vendor_len)); if ((p_cmd = (BT_HDR *) GKI_getpoolbuf(AVRC_META_CMD_POOL_ID)) != NULL) #else assert(AVRC_CMD_POOL_SIZE > (AVRC_MIN_CMD_LEN + p_msg->vendor_len)); if ((p_cmd = (BT_HDR *) GKI_getpoolbuf(AVRC_CMD_POOL_ID)) != NULL) #endif { p_cmd->offset = AVCT_MSG_OFFSET; p_data = (UINT8 *)(p_cmd + 1) + p_cmd->offset; *p_data++ = (p_msg->hdr.ctype & AVRC_CTYPE_MASK); *p_data++ = (p_msg->hdr.subunit_type << AVRC_SUBTYPE_SHIFT) | p_msg->hdr.subunit_id; *p_data++ = AVRC_OP_VENDOR; AVRC_CO_ID_TO_BE_STREAM(p_data, p_msg->company_id); if (p_msg->vendor_len && p_msg->p_vendor_data) { memcpy(p_data, p_msg->p_vendor_data, p_msg->vendor_len); } p_cmd->len = (UINT16) (p_data + p_msg->vendor_len - (UINT8 *)(p_cmd + 1) - p_cmd->offset); p_cmd->layer_specific = AVCT_DATA_CTRL; } return p_cmd; }
/******************************************************************************* ** ** Function rw_t1t_select ** ** Description This function will set the callback function to ** receive data from lower layers and also send rid command ** ** Returns none ** *******************************************************************************/ tNFC_STATUS rw_t1t_select (UINT8 hr[T1T_HR_LEN], UINT8 uid[T1T_CMD_UID_LEN]) { tNFC_STATUS status = NFC_STATUS_FAILED; tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; p_t1t->state = RW_T1T_STATE_NOT_ACTIVATED; /* Alloc cmd buf for retransmissions */ if (p_t1t->p_cur_cmd_buf == NULL) { if ((p_t1t->p_cur_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) == NULL) { RW_TRACE_ERROR0 ("rw_t1t_select: unable to allocate buffer for retransmission"); return status; } } memcpy (p_t1t->hr, hr, T1T_HR_LEN); memcpy (p_t1t->mem, uid, T1T_CMD_UID_LEN); NFC_SetStaticRfCback (rw_t1t_conn_cback); p_t1t->state = RW_T1T_STATE_IDLE; return NFC_STATUS_OK; }
/******************************************************************************* ** ** Function llcp_util_send_connect ** ** Description Send CONNECT PDU ** ** Returns tLLCP_STATUS ** ******************************************************************************/ tLLCP_STATUS llcp_util_send_connect (tLLCP_DLCB *p_dlcb, tLLCP_CONNECTION_PARAMS *p_params) { BT_HDR *p_msg; UINT8 *p; UINT16 miu_len = 0, rw_len = 0, sn_len = 0; if (p_params->miu != LLCP_DEFAULT_MIU) { miu_len = 4; /* TYPE, LEN, 2 bytes MIU */ } if (p_params->rw != LLCP_DEFAULT_RW) { rw_len = 3; /* TYPE, LEN, 1 byte RW */ p_params->rw &= 0x0F; /* only 4 bits */ } if ((strlen (p_params->sn)) && (p_dlcb->remote_sap == LLCP_SAP_SDP)) { sn_len = (UINT16) (2 + strlen (p_params->sn)); /* TYPE, LEN, SN */ } p_msg = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID); if (p_msg) { p_msg->len = LLCP_PDU_HEADER_SIZE + miu_len + rw_len + sn_len; p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE; p = (UINT8 *) (p_msg + 1) + p_msg->offset; UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (p_dlcb->remote_sap, LLCP_PDU_CONNECT_TYPE, p_dlcb->local_sap)); if (miu_len) { UINT8_TO_BE_STREAM (p, LLCP_MIUX_TYPE); UINT8_TO_BE_STREAM (p, LLCP_MIUX_LEN); UINT16_TO_BE_STREAM (p, p_params->miu - LLCP_DEFAULT_MIU); } if (rw_len) { UINT8_TO_BE_STREAM (p, LLCP_RW_TYPE); UINT8_TO_BE_STREAM (p, LLCP_RW_LEN); UINT8_TO_BE_STREAM (p, p_params->rw); } if (sn_len) { UINT8_TO_BE_STREAM (p, LLCP_SN_TYPE); UINT8_TO_BE_STREAM (p, sn_len - 2); memcpy (p, p_params->sn, sn_len - 2); } GKI_enqueue (&llcp_cb.lcb.sig_xmit_q, p_msg); llcp_link_check_send_data (); return LLCP_STATUS_SUCCESS; } return LLCP_STATUS_FAIL; }
/******************************************************************************* ** ** Function attp_build_exec_write_cmd ** ** Description Build a execute write request or response. ** ** Returns None. ** *******************************************************************************/ BT_HDR *attp_build_exec_write_cmd (UINT8 op_code, UINT8 flag) { BT_HDR *p_buf = NULL; UINT8 *p; if ((p_buf = (BT_HDR *)GKI_getpoolbuf(GATT_BUF_POOL_ID)) != NULL) { p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET; p_buf->offset = L2CAP_MIN_OFFSET; p_buf->len = GATT_OP_CODE_SIZE; UINT8_TO_STREAM (p, op_code); if (op_code == GATT_REQ_EXEC_WRITE) { flag &= GATT_PREP_WRITE_EXEC; UINT8_TO_STREAM (p, flag); p_buf->len += 1; } } return p_buf; }
/******************************************************************************* ** ** Function llcp_util_send_frmr ** ** Description Send FRMR PDU ** ** Returns tLLCP_STATUS ** *******************************************************************************/ tLLCP_STATUS llcp_util_send_frmr (tLLCP_DLCB *p_dlcb, UINT8 flags, UINT8 ptype, UINT8 sequence) { BT_HDR *p_msg; UINT8 *p; p_msg = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID); if (p_msg) { p_msg->len = LLCP_PDU_FRMR_SIZE; p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE; p = (UINT8 *) (p_msg + 1) + p_msg->offset; UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (p_dlcb->remote_sap, LLCP_PDU_FRMR_TYPE, p_dlcb->local_sap)); UINT8_TO_BE_STREAM (p, (flags << 4) | ptype); UINT8_TO_BE_STREAM (p, sequence); UINT8_TO_BE_STREAM (p, (p_dlcb->next_tx_seq << 4) | p_dlcb->next_rx_seq); UINT8_TO_BE_STREAM (p, (p_dlcb->rcvd_ack_seq << 4) | p_dlcb->sent_ack_seq); GKI_enqueue (&llcp_cb.lcb.sig_xmit_q, p_msg); llcp_link_check_send_data (); return LLCP_STATUS_SUCCESS; } else { LLCP_TRACE_ERROR0 ("llcp_util_send_frmr (): Out of resource"); return LLCP_STATUS_FAIL; } }
/******************************************************************************* ** ** Function rw_t4t_update_nlen ** ** Description Send UpdateBinary Command to update NLEN to peer ** ** Returns TRUE if success ** *******************************************************************************/ static BOOLEAN rw_t4t_update_nlen (UINT16 ndef_len) { BT_HDR *p_c_apdu; UINT8 *p; RW_TRACE_DEBUG1 ("rw_t4t_update_nlen () NLEN:%d", ndef_len); p_c_apdu = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID); if (!p_c_apdu) { RW_TRACE_ERROR0 ("rw_t4t_update_nlen (): Cannot allocate buffer"); return FALSE; } p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE; p = (UINT8 *) (p_c_apdu + 1) + p_c_apdu->offset; UINT8_TO_BE_STREAM (p, T4T_CMD_CLASS); UINT8_TO_BE_STREAM (p, T4T_CMD_INS_UPDATE_BINARY); UINT16_TO_BE_STREAM (p, 0x0000); /* offset for NLEN */ UINT8_TO_BE_STREAM (p, T4T_FILE_LENGTH_SIZE); UINT16_TO_BE_STREAM (p, ndef_len); p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + T4T_FILE_LENGTH_SIZE; if (!rw_t4t_send_to_lower (p_c_apdu)) { return FALSE; } return TRUE; }
/******************************************************************************* ** ** Function ce_t4t_send_status ** ** Description Send status on R-APDU to peer ** ** Returns TRUE if success ** *******************************************************************************/ static BOOLEAN ce_t4t_send_status (UINT16 status) { BT_HDR *p_r_apdu; UINT8 *p; CE_TRACE_DEBUG1 ("ce_t4t_send_status (): Status:0x%04X", status); p_r_apdu = (BT_HDR *) GKI_getpoolbuf (NFC_CE_POOL_ID); if (!p_r_apdu) { CE_TRACE_ERROR0 ("ce_t4t_send_status (): Cannot allocate buffer"); return FALSE; } p_r_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE; p = (UINT8 *) (p_r_apdu + 1) + p_r_apdu->offset; UINT16_TO_BE_STREAM (p, status); p_r_apdu->len = T4T_RSP_STATUS_WORDS_SIZE; if (!ce_t4t_send_to_lower (p_r_apdu)) { return FALSE; } return TRUE; }
/******************************************************************************* ** ** Function avdt_ccb_ret_cmd ** ** Description This function is called to retransmit the currently ** pending command. The retransmission count is incremented. ** If the count reaches the maximum number of retransmissions, ** the event is treated as a response timeout. ** ** ** Returns void. ** *******************************************************************************/ void avdt_ccb_ret_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) { UINT8 err_code = AVDT_ERR_TIMEOUT; BT_HDR *p_msg; p_ccb->ret_count++; if (p_ccb->ret_count == AVDT_RET_MAX) { /* command failed */ p_ccb->ret_count = 0; avdt_ccb_cmd_fail(p_ccb, (tAVDT_CCB_EVT *) &err_code); /* go to next queued command */ avdt_ccb_snd_cmd(p_ccb, p_data); } else { /* if command pending and we're not congested and not sending a fragment */ if ((!p_ccb->cong) && (p_ccb->p_curr_msg == NULL) && (p_ccb->p_curr_cmd != NULL)) { /* make copy of message in p_curr_cmd and send it */ if ((p_msg = (BT_HDR *) GKI_getpoolbuf(AVDT_CMD_POOL_ID)) != NULL) { memcpy(p_msg, p_ccb->p_curr_cmd, (sizeof(BT_HDR) + p_ccb->p_curr_cmd->offset + p_ccb->p_curr_cmd->len)); avdt_msg_send(p_ccb, p_msg); } } /* restart timer */ btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_AVDT_CCB_RET, avdt_cb.rcb.ret_tout); } }
/******************************************************************************* ** ** Function nfc_hal_dm_send_bt_cmd ** ** Description Send BT message to NFCC while initializing BRCM NFCC ** ** Returns void ** *******************************************************************************/ void nfc_hal_dm_send_bt_cmd (const UINT8 *p_data, UINT16 len, tNFC_HAL_BTVSC_CPLT_CBACK *p_cback) { NFC_HDR *p_buf; HAL_TRACE_DEBUG1 ("nfc_hal_dm_send_bt_cmd (): nci_wait_rsp = 0x%x", nfc_hal_cb.ncit_cb.nci_wait_rsp); if (nfc_hal_cb.ncit_cb.nci_wait_rsp != NFC_HAL_WAIT_RSP_NONE) { HAL_TRACE_ERROR0 ("nfc_hal_dm_send_bt_cmd(): no command window"); return; } if ((p_buf = (NFC_HDR *) GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL) { nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_PROP; p_buf->offset = NFC_HAL_NCI_MSG_OFFSET_SIZE; p_buf->len = len; memcpy ((UINT8*) (p_buf + 1) + p_buf->offset, p_data, len); /* save the callback for NCI VSCs) */ nfc_hal_cb.ncit_cb.p_vsc_cback = (void *)p_cback; nfc_hal_cb.ncit_cb.p_pend_cmd = p_buf; if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_IDLE) { NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_CONTROL_DONE); nfc_hal_cb.p_stack_cback (HAL_NFC_REQUEST_CONTROL_EVT, HAL_NFC_STATUS_OK); return; } nfc_hal_dm_send_pend_cmd(); } }
/******************************************************************************* ** ** Function rw_t2t_send_cmd ** ** Description This function composes a Type 2 Tag command and send it via ** NCI to NFCC. ** ** Returns NFC_STATUS_OK if the command is successfuly sent to NCI ** otherwise, error status ** *******************************************************************************/ tNFC_STATUS rw_t2t_send_cmd (UINT8 opcode, UINT8 *p_dat) { tNFC_STATUS status = NFC_STATUS_FAILED; tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; const tT2T_CMD_RSP_INFO *p_cmd_rsp_info = t2t_cmd_to_rsp_info (opcode); BT_HDR *p_data; UINT8 *p; if (p_cmd_rsp_info) { /* a valid opcode for RW */ p_data = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID); if (p_data) { p_t2t->p_cmd_rsp_info = (tT2T_CMD_RSP_INFO *) p_cmd_rsp_info; p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE; p = (UINT8 *) (p_data + 1) + p_data->offset; UINT8_TO_STREAM (p, opcode); if (p_dat) { ARRAY_TO_STREAM (p, p_dat, (p_cmd_rsp_info->cmd_len - 1)); } p_data->len = p_cmd_rsp_info->cmd_len; /* Indicate first attempt to send command, back up cmd buffer in case needed for retransmission */ rw_cb.cur_retry = 0; memcpy (p_t2t->p_cur_cmd_buf, p_data, sizeof (BT_HDR) + p_data->offset + p_data->len); #if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE)) /* Update stats */ rw_main_update_tx_stats (p_data->len, FALSE); #endif RW_TRACE_EVENT2 ("RW SENT [%s]:0x%x CMD", t2t_info_to_str (p_cmd_rsp_info), p_cmd_rsp_info->opcode); if ((status = NFC_SendData (NFC_RF_CONN_ID, p_data)) == NFC_STATUS_OK) { nfc_start_quick_timer (&p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE, (RW_T2T_TOUT_RESP*QUICK_TIMER_TICKS_PER_SEC) / 1000); } else { #if (BT_TRACE_VERBOSE == TRUE) RW_TRACE_ERROR2 ("T2T NFC Send data failed. state=%s substate=%s ", rw_t2t_get_state_name (p_t2t->state), rw_t2t_get_substate_name (p_t2t->substate)); #else RW_TRACE_ERROR2 ("T2T NFC Send data failed. state=0x%02X substate=0x%02X ", p_t2t->state, p_t2t->substate); #endif } } else { status = NFC_STATUS_NO_BUFFERS; } } return status; }
/******************************************************************************* ** ** Function rw_t1t_send_dyn_cmd ** ** Description This function composes a Type 1 Tag command for dynamic memory ** and send through NCI to NFCC. ** ** Returns NFC_STATUS_OK if the command is successfuly sent to NCI ** otherwise, error status ** *******************************************************************************/ tNFC_STATUS rw_t1t_send_dyn_cmd (UINT8 opcode, UINT8 add, UINT8 *p_dat) { tNFC_STATUS status = NFC_STATUS_FAILED; tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; const tT1T_CMD_RSP_INFO *p_cmd_rsp_info = t1t_cmd_to_rsp_info (opcode); BT_HDR *p_data; UINT8 *p; if (p_cmd_rsp_info) { /* a valid opcode for RW */ p_data = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID); if (p_data) { p_t1t->p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *) p_cmd_rsp_info; p_t1t->addr = add; p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE; p = (UINT8 *) (p_data + 1) + p_data->offset; UINT8_TO_BE_STREAM (p, opcode); UINT8_TO_BE_STREAM (p, add); if (p_dat) { ARRAY_TO_STREAM (p, p_dat, 8); } else { memset (p, 0, 8); p += 8; } ARRAY_TO_STREAM (p, p_t1t->mem, T1T_CMD_UID_LEN); p_data->len = p_cmd_rsp_info->cmd_len; /* Indicate first attempt to send command, back up cmd buffer in case needed for retransmission */ rw_cb.cur_retry = 0; memcpy (p_t1t->p_cur_cmd_buf, p_data, sizeof (BT_HDR) + p_data->offset + p_data->len); #if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE)) /* Update stats */ rw_main_update_tx_stats (p_data->len, FALSE); #endif /* RW_STATS_INCLUDED */ RW_TRACE_EVENT2 ("RW SENT [%s]:0x%x CMD", t1t_info_to_str (p_cmd_rsp_info), p_cmd_rsp_info->opcode); if ((status = NFC_SendData (NFC_RF_CONN_ID, p_data)) == NFC_STATUS_OK) { nfc_start_quick_timer (&p_t1t->timer, NFC_TTYPE_RW_T1T_RESPONSE, (RW_T1T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000); } } else { status = NFC_STATUS_NO_BUFFERS; } } return status; }
static UINT8 L2cap_DataWrite (UINT16 cid, char *p_data, UINT32 len) { BTIF_TRACE_DEBUG("L2cap_DataWrite:: Invoked"); BT_HDR *p_msg = NULL;(BT_HDR *) GKI_getpoolbuf (GKI_POOL_ID_3); UINT8 *ptr, *p_start; p_msg = (BT_HDR *) GKI_getpoolbuf (GKI_POOL_ID_3); BTIF_TRACE_DEBUG("GKI_getpoolbuf"); if (!p_msg) { BTIF_TRACE_DEBUG("No resource to allocate"); return BT_STATUS_FAIL; } p_msg->offset = L2CAP_MIN_OFFSET; ptr = p_start = (UINT8 *)(p_msg + 1) + L2CAP_MIN_OFFSET; p_msg->len = len; //Sends len bytes, irrespective of what you copy to the buffer memcpy(ptr, p_data, len); return L2CA_DataWrite(cid, p_msg); }
/******************************************************************************* ** ** Function rw_t4t_select_application ** ** Description Select Application ** ** NDEF Tag Application Select - C-APDU ** ** CLA INS P1 P2 Lc Data(AID) Le ** V1.0: 00 A4 04 00 07 D2760000850100 - ** V2.0: 00 A4 04 00 07 D2760000850101 00 ** ** Returns TRUE if success ** *******************************************************************************/ static BOOLEAN rw_t4t_select_application (UINT8 version) { BT_HDR *p_c_apdu; UINT8 *p; RW_TRACE_DEBUG1 ("rw_t4t_select_application () version:0x%X", version); p_c_apdu = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID); if (!p_c_apdu) { RW_TRACE_ERROR0 ("rw_t4t_select_application (): Cannot allocate buffer"); return FALSE; } p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE; p = (UINT8 *) (p_c_apdu + 1) + p_c_apdu->offset; UINT8_TO_BE_STREAM (p, T4T_CMD_CLASS); UINT8_TO_BE_STREAM (p, T4T_CMD_INS_SELECT); UINT8_TO_BE_STREAM (p, T4T_CMD_P1_SELECT_BY_NAME); UINT8_TO_BE_STREAM (p, T4T_CMD_P2_FIRST_OR_ONLY_00H); if (version == T4T_VERSION_1_0) /* this is for V1.0 */ { UINT8_TO_BE_STREAM (p, T4T_V10_NDEF_TAG_AID_LEN); memcpy (p, t4t_v10_ndef_tag_aid, T4T_V10_NDEF_TAG_AID_LEN); p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + T4T_V10_NDEF_TAG_AID_LEN; } else if (version == T4T_VERSION_2_0) /* this is for V2.0 */ { UINT8_TO_BE_STREAM (p, T4T_V20_NDEF_TAG_AID_LEN); memcpy (p, t4t_v20_ndef_tag_aid, T4T_V20_NDEF_TAG_AID_LEN); p += T4T_V20_NDEF_TAG_AID_LEN; UINT8_TO_BE_STREAM (p, 0x00); /* Le set to 0x00 */ p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + T4T_V20_NDEF_TAG_AID_LEN + 1; } else { return FALSE; } if (!rw_t4t_send_to_lower (p_c_apdu)) { return FALSE; } return TRUE; }
/******************************************************************************* ** ** Function bta_pan_data_buf_ind_cback ** ** Description data indication callback from pan profile ** ** ** Returns void ** *******************************************************************************/ static void bta_pan_data_buf_ind_cback(UINT16 handle, BD_ADDR src, BD_ADDR dst, UINT16 protocol, BT_HDR *p_buf, BOOLEAN ext, BOOLEAN forward) { tBTA_PAN_SCB *p_scb; BT_HDR * p_event; BT_HDR *p_new_buf; if ( sizeof(tBTA_PAN_DATA_PARAMS) > p_buf->offset ) { /* offset smaller than data structure in front of actual data */ p_new_buf = (BT_HDR *)GKI_getpoolbuf( PAN_POOL_ID ); if(!p_new_buf) { APPL_TRACE_WARNING0("Cannot get a PAN GKI buffer"); GKI_freebuf( p_buf ); return; } else { memcpy( (UINT8 *)(p_new_buf+1)+sizeof(tBTA_PAN_DATA_PARAMS), (UINT8 *)(p_buf+1)+p_buf->offset, p_buf->len ); p_new_buf->len = p_buf->len; p_new_buf->offset = sizeof(tBTA_PAN_DATA_PARAMS); GKI_freebuf( p_buf ); } } else { p_new_buf = p_buf; } /* copy params into the space before the data */ bdcpy(((tBTA_PAN_DATA_PARAMS *)p_new_buf)->src, src); bdcpy(((tBTA_PAN_DATA_PARAMS *)p_new_buf)->dst, dst); ((tBTA_PAN_DATA_PARAMS *)p_new_buf)->protocol = protocol; ((tBTA_PAN_DATA_PARAMS *)p_new_buf)->ext = ext; ((tBTA_PAN_DATA_PARAMS *)p_new_buf)->forward = forward; if((p_scb = bta_pan_scb_by_handle(handle)) == NULL) { GKI_freebuf( p_new_buf ); return; } GKI_enqueue(&p_scb->data_queue, p_new_buf); if ((p_event = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) { p_event->layer_specific = handle; p_event->event = BTA_PAN_RX_FROM_BNEP_READY_EVT; bta_sys_sendmsg(p_event); } }
/******************************************************************************* ** ** Function rw_t4t_update_file ** ** Description Send UpdateBinary Command to peer ** ** Returns TRUE if success ** *******************************************************************************/ static BOOLEAN rw_t4t_update_file (void) { tRW_T4T_CB *p_t4t = &rw_cb.tcb.t4t; BT_HDR *p_c_apdu; UINT8 *p; UINT16 length; RW_TRACE_DEBUG2 ("rw_t4t_update_file () rw_offset:%d, rw_length:%d", p_t4t->rw_offset, p_t4t->rw_length); p_c_apdu = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID); if (!p_c_apdu) { RW_TRACE_ERROR0 ("rw_t4t_write_file (): Cannot allocate buffer"); return FALSE; } /* try to send all of remaining data */ length = p_t4t->rw_length; /* adjust updating length if payload is bigger than max size per single command */ if (length > p_t4t->max_update_size) { length = (UINT8) (p_t4t->max_update_size); } p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE; p = (UINT8 *) (p_c_apdu + 1) + p_c_apdu->offset; UINT8_TO_BE_STREAM (p, T4T_CMD_CLASS); UINT8_TO_BE_STREAM (p, T4T_CMD_INS_UPDATE_BINARY); UINT16_TO_BE_STREAM (p, p_t4t->rw_offset); UINT8_TO_BE_STREAM (p, length); memcpy (p, p_t4t->p_update_data, length); p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + length; if (!rw_t4t_send_to_lower (p_c_apdu)) { return FALSE; } /* adjust offset, length and pointer for remaining data */ p_t4t->rw_offset += length; p_t4t->rw_length -= length; p_t4t->p_update_data += length; return TRUE; }
/******************************************************************************* ** ** Function rw_t4t_read_file ** ** Description Send ReadBinary Command to peer ** ** Returns TRUE if success ** *******************************************************************************/ static BOOLEAN rw_t4t_read_file (UINT16 offset, UINT16 length, BOOLEAN is_continue) { tRW_T4T_CB *p_t4t = &rw_cb.tcb.t4t; BT_HDR *p_c_apdu; UINT8 *p; RW_TRACE_DEBUG3 ("rw_t4t_read_file () offset:%d, length:%d, is_continue:%d, ", offset, length, is_continue); p_c_apdu = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID); if (!p_c_apdu) { RW_TRACE_ERROR0 ("rw_t4t_read_file (): Cannot allocate buffer"); return FALSE; } /* if this is the first reading */ if (is_continue == FALSE) { /* initialise starting offset and total length */ /* these will be updated when receiving response */ p_t4t->rw_offset = offset; p_t4t->rw_length = length; } /* adjust reading length if payload is bigger than max size per single command */ if (length > p_t4t->max_read_size) { length = (UINT8) (p_t4t->max_read_size); } p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE; p = (UINT8 *) (p_c_apdu + 1) + p_c_apdu->offset; UINT8_TO_BE_STREAM (p, T4T_CMD_CLASS); UINT8_TO_BE_STREAM (p, T4T_CMD_INS_READ_BINARY); UINT16_TO_BE_STREAM (p, offset); UINT8_TO_BE_STREAM (p, length); /* Le */ p_c_apdu->len = T4T_CMD_MIN_HDR_SIZE + 1; /* adding Le */ if (!rw_t4t_send_to_lower (p_c_apdu)) { return FALSE; } return TRUE; }
/******************************************************************************* ** ** Function llcp_util_send_cc ** ** Description Send CC PDU ** ** Returns tLLCP_STATUS ** ******************************************************************************/ tLLCP_STATUS llcp_util_send_cc (tLLCP_DLCB *p_dlcb, tLLCP_CONNECTION_PARAMS *p_params) { BT_HDR *p_msg; UINT8 *p; UINT16 miu_len = 0, rw_len = 0; if (p_params->miu != LLCP_DEFAULT_MIU) { miu_len = 4; } if (p_params->rw != LLCP_DEFAULT_RW) { rw_len = 3; p_params->rw &= 0x0F; } p_msg = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID); if (p_msg) { p_msg->len = LLCP_PDU_HEADER_SIZE + miu_len + rw_len; p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE; p = (UINT8 *) (p_msg + 1) + p_msg->offset; UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (p_dlcb->remote_sap, LLCP_PDU_CC_TYPE, p_dlcb->local_sap)); if (miu_len) { UINT8_TO_BE_STREAM (p, LLCP_MIUX_TYPE); UINT8_TO_BE_STREAM (p, LLCP_MIUX_LEN); UINT16_TO_BE_STREAM (p, p_params->miu - LLCP_DEFAULT_MIU); } if (rw_len) { UINT8_TO_BE_STREAM (p, LLCP_RW_TYPE); UINT8_TO_BE_STREAM (p, LLCP_RW_LEN); UINT8_TO_BE_STREAM (p, p_params->rw); } GKI_enqueue (&llcp_cb.lcb.sig_xmit_q, p_msg); llcp_link_check_send_data (); return LLCP_STATUS_SUCCESS; } return LLCP_STATUS_FAIL; }
/******************************************************************************* ** ** Function nfc_hal_dm_send_bt_cmd ** ** Description Send BT message to NFCC while initializing BRCM NFCC ** ** Returns void ** *******************************************************************************/ void nfc_hal_dm_send_bt_cmd (const UINT8 *p_data, UINT16 len, tNFC_HAL_BTVSC_CPLT_CBACK *p_cback) { NFC_HDR *p_buf; char buff[300]; char tmp[4]; buff[0] = 0; int i; HAL_TRACE_DEBUG1 ("nfc_hal_dm_send_bt_cmd (): nci_wait_rsp = 0x%x", nfc_hal_cb.ncit_cb.nci_wait_rsp); for (i = 0; i < len; i++) { sprintf (tmp, "%02x ", p_data[i]); strcat(buff, tmp); } HAL_TRACE_DEBUG2 ("nfc_hal_dm_send_bt_cmd (): HCI Write (%d bytes): %s", len, buff); if (nfc_hal_cb.ncit_cb.nci_wait_rsp != NFC_HAL_WAIT_RSP_NONE) { HAL_TRACE_ERROR0 ("nfc_hal_dm_send_bt_cmd(): no command window"); return; } if ((p_buf = (NFC_HDR *) GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL) { nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_PROP; p_buf->offset = NFC_HAL_NCI_MSG_OFFSET_SIZE; p_buf->len = len; memcpy ((UINT8*) (p_buf + 1) + p_buf->offset, p_data, len); /* save the callback for NCI VSCs) */ nfc_hal_cb.ncit_cb.p_vsc_cback = (void *)p_cback; nfc_hal_cb.ncit_cb.p_pend_cmd = p_buf; if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_IDLE) { NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_CONTROL_DONE); nfc_hal_cb.p_stack_cback (HAL_NFC_REQUEST_CONTROL_EVT, HAL_NFC_STATUS_OK); return; } nfc_hal_dm_send_pend_cmd(); } }
/****************************************************************************** ** ** Function AVRC_UnitCmd ** ** Description Send a UNIT INFO command to the peer device. This ** function can only be called for controller role connections. ** Any response message from the peer is passed back through ** the tAVRC_MSG_CBACK callback function. ** ** Input Parameters: ** handle: Handle of this connection. ** ** label: Transaction label. ** ** Output Parameters: ** None. ** ** Returns AVRC_SUCCESS if successful. ** AVRC_BAD_HANDLE if handle is invalid. ** ******************************************************************************/ UINT16 AVRC_UnitCmd(UINT8 handle, UINT8 label) { BT_HDR *p_cmd; UINT8 *p_data; if ((p_cmd = (BT_HDR *) GKI_getpoolbuf(AVRC_CMD_POOL_ID)) != NULL) { p_cmd->offset = AVCT_MSG_OFFSET; p_data = (UINT8 *)(p_cmd + 1) + p_cmd->offset; *p_data++ = AVRC_CMD_STATUS; /* unit & id ignore */ *p_data++ = (AVRC_SUB_UNIT << AVRC_SUBTYPE_SHIFT) | AVRC_SUBID_IGNORE; *p_data++ = AVRC_OP_UNIT_INFO; memset(p_data, AVRC_CMD_OPRND_PAD, AVRC_UNIT_OPRND_BYTES); p_cmd->len = p_data + AVRC_UNIT_OPRND_BYTES - (UINT8 *)(p_cmd + 1) - p_cmd->offset; p_cmd->layer_specific = AVCT_DATA_CTRL; } return AVCT_MsgReq( handle, label, AVCT_CMD, p_cmd); }
/******************************************************************************* ** ** Function rw_t4t_select_file ** ** Description Send Select Command (by File ID) to peer ** ** Returns TRUE if success ** *******************************************************************************/ static BOOLEAN rw_t4t_select_file (UINT16 file_id) { BT_HDR *p_c_apdu; UINT8 *p; RW_TRACE_DEBUG1 ("rw_t4t_select_file (): File ID:0x%04X", file_id); p_c_apdu = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID); if (!p_c_apdu) { RW_TRACE_ERROR0 ("rw_t4t_select_file (): Cannot allocate buffer"); return FALSE; } p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE; p = (UINT8 *) (p_c_apdu + 1) + p_c_apdu->offset; UINT8_TO_BE_STREAM (p, T4T_CMD_CLASS); UINT8_TO_BE_STREAM (p, T4T_CMD_INS_SELECT); UINT8_TO_BE_STREAM (p, T4T_CMD_P1_SELECT_BY_FILE_ID); /* if current version mapping is V2.0 */ if (rw_cb.tcb.t4t.version == T4T_VERSION_2_0) { UINT8_TO_BE_STREAM (p, T4T_CMD_P2_FIRST_OR_ONLY_0CH); } else /* version 1.0 */ { UINT8_TO_BE_STREAM (p, T4T_CMD_P2_FIRST_OR_ONLY_00H); } UINT8_TO_BE_STREAM (p, T4T_FILE_ID_SIZE); UINT16_TO_BE_STREAM (p, file_id); p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + T4T_FILE_ID_SIZE; if (!rw_t4t_send_to_lower (p_c_apdu)) { return FALSE; } return TRUE; }
/******************************************************************************* ** ** Function rw_t2t_resume_op ** ** Description This function will continue operation after moving to new ** sector ** ** Returns tNFC_STATUS ** *******************************************************************************/ static void rw_t2t_resume_op (void) { tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; tRW_READ_DATA evt_data; BT_HDR *p_cmd_buf; tRW_EVENT event; const tT2T_CMD_RSP_INFO *p_cmd_rsp_info = (tT2T_CMD_RSP_INFO *) rw_cb.tcb.t2t.p_cmd_rsp_info; UINT8 *p; /* Move back to the substate where we were before changing sector */ p_t2t->substate = p_t2t->prev_substate; p = (UINT8 *) (p_t2t->p_sec_cmd_buf + 1) + p_t2t->p_sec_cmd_buf->offset; p_cmd_rsp_info = t2t_cmd_to_rsp_info ((UINT8) *p); p_t2t->p_cmd_rsp_info = (tT2T_CMD_RSP_INFO *) p_cmd_rsp_info; /* allocate a new buffer for message */ if ((p_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL) { memcpy (p_cmd_buf, p_t2t->p_sec_cmd_buf, sizeof (BT_HDR) + p_t2t->p_sec_cmd_buf->offset + p_t2t->p_sec_cmd_buf->len); memcpy (p_t2t->p_cur_cmd_buf, p_t2t->p_sec_cmd_buf, sizeof (BT_HDR) + p_t2t->p_sec_cmd_buf->offset + p_t2t->p_sec_cmd_buf->len); #if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE)) /* Update stats */ rw_main_update_tx_stats (p_cmd_buf->len, TRUE); #endif if (NFC_SendData (NFC_RF_CONN_ID, p_cmd_buf) == NFC_STATUS_OK) { /* Start timer for waiting for response */ nfc_start_quick_timer (&p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE, (RW_T2T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000); } else { /* failure - could not send buffer */ evt_data.p_data = NULL; evt_data.status = NFC_STATUS_FAILED; event = rw_t2t_info_to_event (p_cmd_rsp_info); rw_t2t_handle_op_complete (); (*rw_cb.p_cback) (event, (tRW_DATA *) &evt_data); } } }
/******************************************************************************* ** ** Function llcp_util_send_disc ** ** Description Send DISC PDU ** ** Returns void ** *******************************************************************************/ void llcp_util_send_disc (UINT8 dsap, UINT8 ssap) { BT_HDR *p_msg; UINT8 *p; p_msg = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID); if (p_msg) { p_msg->len = LLCP_PDU_DISC_SIZE; p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE; p = (UINT8 *) (p_msg + 1) + p_msg->offset; UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (dsap, LLCP_PDU_DISC_TYPE, ssap)); GKI_enqueue (&llcp_cb.lcb.sig_xmit_q, p_msg); llcp_link_check_send_data (); } }
/******************************************************************************* ** ** Function avdt_ccb_snd_cmd ** ** Description This function is called the send the next command, ** if any, in the command queue. ** ** ** Returns void. ** *******************************************************************************/ void avdt_ccb_snd_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) { BT_HDR *p_msg; /* do we have commands to send? send next command; make sure we're clear; ** not congested, not sending fragment, not waiting for response */ if ((!p_ccb->cong) && (p_ccb->p_curr_msg == NULL) && (p_ccb->p_curr_cmd == NULL)) { if ((p_msg = (BT_HDR *) GKI_dequeue(&p_ccb->cmd_q)) != NULL) { /* make a copy of buffer in p_curr_cmd */ if ((p_ccb->p_curr_cmd = (BT_HDR *) GKI_getpoolbuf(AVDT_CMD_POOL_ID)) != NULL) { memcpy(p_ccb->p_curr_cmd, p_msg, (sizeof(BT_HDR) + p_msg->offset + p_msg->len)); avdt_msg_send(p_ccb, p_msg); } } } }
/******************************************************************************* ** ** Function rw_t2t_sector_change ** ** Description This function issues Type 2 Tag SECTOR-SELECT command ** packet 1. ** ** Returns tNFC_STATUS ** *******************************************************************************/ tNFC_STATUS rw_t2t_sector_change (UINT8 sector) { tNFC_STATUS status; BT_HDR *p_data; UINT8 *p; tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; if ((p_data = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) == NULL) { RW_TRACE_ERROR0 ("rw_t2t_sector_change - No buffer"); return (NFC_STATUS_NO_BUFFERS); } p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE; p = (UINT8 *) (p_data + 1) + p_data->offset; UINT8_TO_BE_STREAM (p, sector); UINT8_TO_BE_STREAM (p, 0x00); UINT8_TO_BE_STREAM (p, 0x00); UINT8_TO_BE_STREAM (p, 0x00); p_data->len = 4; if ((status = NFC_SendData (NFC_RF_CONN_ID , p_data)) == NFC_STATUS_OK) { /* Passive rsp command and suppose not to get response to this command */ p_t2t->p_cmd_rsp_info = NULL; p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR; RW_TRACE_EVENT0 ("rw_t2t_sector_change Sent Second Command"); nfc_start_quick_timer (&p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE, (RW_T2T_SEC_SEL_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000); } else { RW_TRACE_ERROR1 ("rw_t2t_sector_change Send failed at rw_t2t_send_cmd, error: %u", status); } return status; }
/******************************************************************************* ** ** Function nfc_hal_dm_send_nci_cmd ** ** Description Send NCI command to NFCC while initializing BRCM NFCC ** ** Returns void ** *******************************************************************************/ void nfc_hal_dm_send_nci_cmd (const UINT8 *p_data, UINT16 len, tNFC_HAL_NCI_CBACK *p_cback) { NFC_HDR *p_buf; UINT8 *ps; HAL_TRACE_DEBUG1 ("nfc_hal_dm_send_nci_cmd (): nci_wait_rsp = 0x%x", nfc_hal_cb.ncit_cb.nci_wait_rsp); if (nfc_hal_cb.ncit_cb.nci_wait_rsp != NFC_HAL_WAIT_RSP_NONE) { HAL_TRACE_ERROR0 ("nfc_hal_dm_send_nci_cmd(): no command window"); return; } if ((p_buf = (NFC_HDR *)GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL) { nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_VSC; p_buf->offset = NFC_HAL_NCI_MSG_OFFSET_SIZE; p_buf->event = NFC_HAL_EVT_TO_NFC_NCI; p_buf->len = len; memcpy ((UINT8*) (p_buf + 1) + p_buf->offset, p_data, len); /* Keep a copy of the command and send to NCI transport */ /* save the message header to double check the response */ ps = (UINT8 *)(p_buf + 1) + p_buf->offset; memcpy(nfc_hal_cb.ncit_cb.last_hdr, ps, NFC_HAL_SAVED_HDR_SIZE); memcpy(nfc_hal_cb.ncit_cb.last_cmd, ps + NCI_MSG_HDR_SIZE, NFC_HAL_SAVED_CMD_SIZE); /* save the callback for NCI VSCs */ nfc_hal_cb.ncit_cb.p_vsc_cback = (void *)p_cback; nfc_hal_nci_send_cmd (p_buf); /* start NFC command-timeout timer */ nfc_hal_main_start_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer, (UINT16)(NFC_HAL_TTYPE_NCI_WAIT_RSP), ((UINT32) NFC_HAL_CMD_TOUT) * QUICK_TIMER_TICKS_PER_SEC / 1000); } }
/******************************************************************************* ** ** Function CE_SendRawFrame ** ** Description This function sends a raw frame to the peer device. ** ** Returns tNFC_STATUS ** *******************************************************************************/ tNFC_STATUS CE_SendRawFrame (UINT8 *p_raw_data, UINT16 data_len) { tNFC_STATUS status = NFC_STATUS_FAILED; BT_HDR *p_data; UINT8 *p; if (ce_cb.p_cback) { /* a valid opcode for RW */ p_data = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID); if (p_data) { p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE; p = (UINT8 *) (p_data + 1) + p_data->offset; memcpy (p, p_raw_data, data_len); p_data->len = data_len; CE_TRACE_EVENT1 ("CE SENT raw frame (0x%x)", data_len); status = NFC_SendData (NFC_RF_CONN_ID, p_data); } } return status; }
/******************************************************************************* ** ** Function nfc_hal_send_credit_ntf_for_cid ** ** Description This function is called to send credit ntf ** for the specified connection id to nfc task ** ** Returns void ** *******************************************************************************/ static void nfc_hal_send_credit_ntf_for_cid (UINT8 cid) { NFC_HDR *p_msg; UINT8 *p, *ps; /* Start of new message. Allocate a buffer for message */ if ((p_msg = (NFC_HDR *) GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL) { /* Initialize NFC_HDR */ p_msg->len = NCI_DATA_HDR_SIZE + 0x03; p_msg->event = 0; p_msg->offset = 0; p_msg->layer_specific = 0; p = (UINT8 *) (p_msg + 1) + p_msg->offset; ps = p; NCI_MSG_BLD_HDR0(p, NCI_MT_NTF, NCI_GID_CORE); NCI_MSG_BLD_HDR1(p, NCI_MSG_CORE_CONN_CREDITS); UINT8_TO_STREAM (p, 0x03); /* Number of credit entries */ *p++ = 0x01; /* Connection id of the credit ntf */ *p++ = cid; /* Number of credits */ *p = 0x01; #ifdef DISP_NCI DISP_NCI (ps, (UINT16) p_msg->len, TRUE); #endif nfc_hal_send_nci_msg_to_nfc_task (p_msg); } else { HAL_TRACE_ERROR0 ("Unable to allocate buffer for Sending credit ntf to stack"); } }
static void btu_exec_tap_fd_read(void *p_param) { struct pollfd ufd; int fd = (int)p_param; if (fd == -1 || fd != btpan_cb.tap_fd) return; // Don't occupy BTU context too long, avoid GKI buffer overruns and // give other profiles a chance to run by limiting the amount of memory // PAN can use from the shared pool buffer. for(int i = 0; i < PAN_POOL_MAX && btif_is_enabled() && btpan_cb.flow; i++) { BT_HDR *buffer = (BT_HDR *)GKI_getpoolbuf(PAN_POOL_ID); if (!buffer) { BTIF_TRACE_WARNING("%s unable to allocate buffer for packet.", __func__); break; } buffer->offset = PAN_MINIMUM_OFFSET; buffer->len = GKI_get_buf_size(buffer) - sizeof(BT_HDR) - buffer->offset; UINT8 *packet = (UINT8 *)buffer + sizeof(BT_HDR) + buffer->offset; // If we don't have an undelivered packet left over, pull one from the TAP driver. // We save it in the congest_packet right away in case we can't deliver it in this // attempt. if (!btpan_cb.congest_packet_size) { ssize_t ret = read(fd, btpan_cb.congest_packet, sizeof(btpan_cb.congest_packet)); switch (ret) { case -1: BTIF_TRACE_ERROR("%s unable to read from driver: %s", __func__, strerror(errno)); GKI_freebuf(buffer); return; case 0: BTIF_TRACE_WARNING("%s end of file reached.", __func__); GKI_freebuf(buffer); return; default: btpan_cb.congest_packet_size = ret; break; } } memcpy(packet, btpan_cb.congest_packet, MIN(btpan_cb.congest_packet_size, buffer->len)); buffer->len = MIN(btpan_cb.congest_packet_size, buffer->len); if (buffer->len > sizeof(tETH_HDR) && should_forward((tETH_HDR *)packet)) { // Extract the ethernet header from the buffer since the PAN_WriteBuf inside // forward_bnep can't handle two pointers that point inside the same GKI buffer. tETH_HDR hdr; memcpy(&hdr, packet, sizeof(tETH_HDR)); // Skip the ethernet header. buffer->len -= sizeof(tETH_HDR); buffer->offset += sizeof(tETH_HDR); if (forward_bnep(&hdr, buffer) != FORWARD_CONGEST) btpan_cb.congest_packet_size = 0; } else { BTIF_TRACE_WARNING("%s dropping packet of length %d", __func__, buffer->len); btpan_cb.congest_packet_size = 0; GKI_freebuf(buffer); } // Bail out of the loop if reading from the TAP fd would block. ufd.fd = fd; ufd.events = POLLIN; ufd.revents = 0; if(poll(&ufd, 1, 0) <= 0 || IS_EXCEPTION(ufd.revents)) { btsock_thread_add_fd(pan_pth, fd, 0, SOCK_THREAD_FD_RD, 0); return; } } }
/******************************************************************************* ** ** Function llcp_sdp_send_sdres ** ** Description Send Service Discovery Response ** ** ** Returns LLCP_STATUS ** *******************************************************************************/ static tLLCP_STATUS llcp_sdp_send_sdres (UINT8 tid, UINT8 sap) { tLLCP_STATUS status; UINT16 available_bytes; LLCP_TRACE_DEBUG2 ("llcp_sdp_send_sdres (): tid=0x%x, SAP=0x%x", tid, sap); /* if there is no pending SNL */ if (!llcp_cb.sdp_cb.p_snl) { llcp_cb.sdp_cb.p_snl = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID); if (llcp_cb.sdp_cb.p_snl) { llcp_cb.sdp_cb.p_snl->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + LLCP_PDU_HEADER_SIZE; llcp_cb.sdp_cb.p_snl->len = 0; } } if (llcp_cb.sdp_cb.p_snl) { available_bytes = GKI_get_buf_size (llcp_cb.sdp_cb.p_snl) - BT_HDR_SIZE - llcp_cb.sdp_cb.p_snl->offset - llcp_cb.sdp_cb.p_snl->len; /* if SDRES parameter can be added in SNL */ if ( (available_bytes >= 2 + LLCP_SDRES_LEN) &&(llcp_cb.sdp_cb.p_snl->len + 2 + LLCP_SDRES_LEN <= llcp_cb.lcb.effective_miu) ) { llcp_sdp_add_sdres (tid, sap); status = LLCP_STATUS_SUCCESS; } else { /* send pending SNL PDU to LM */ llcp_sdp_check_send_snl (); llcp_cb.sdp_cb.p_snl = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID); if (llcp_cb.sdp_cb.p_snl) { llcp_cb.sdp_cb.p_snl->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + LLCP_PDU_HEADER_SIZE; llcp_cb.sdp_cb.p_snl->len = 0; llcp_sdp_add_sdres (tid, sap); status = LLCP_STATUS_SUCCESS; } else { status = LLCP_STATUS_FAIL; } } } else { status = LLCP_STATUS_FAIL; } /* if LM is waiting for PDUs from upper layer */ if ( (status == LLCP_STATUS_SUCCESS) &&(llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT) ) { llcp_link_check_send_data (); } return status; }