1 /****************************************************************************** 2 * 3 * Copyright (C) 2010-2014 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 file contains functions that NCI vendor specific interface with the 22 * NFCC. On the receive side, it routes events to the appropriate handler 23 * (callback). On the transmit side, it manages the command transmission. 24 * 25 ******************************************************************************/ 26 #include <string.h> 27 28 #include <android-base/stringprintf.h> 29 #include <base/logging.h> 30 31 #include "nfc_target.h" 32 33 #include "gki.h" 34 #include "nfc_int.h" 35 36 using android::base::StringPrintf; 37 38 /**************************************************************************** 39 ** Declarations 40 ****************************************************************************/ 41 42 /******************************************************************************* 43 ** 44 ** Function NFC_RegVSCback 45 ** 46 ** Description This function is called to register or de-register a 47 ** callback function to receive Proprietary NCI response and 48 ** notification events. The maximum number of callback 49 ** functions allowed is NFC_NUM_VS_CBACKS 50 ** 51 ** Returns tNFC_STATUS 52 ** 53 *******************************************************************************/ 54 tNFC_STATUS NFC_RegVSCback(bool is_register, tNFC_VS_CBACK* p_cback) { 55 tNFC_STATUS status = NFC_STATUS_FAILED; 56 int i; 57 58 if (is_register) { 59 for (i = 0; i < NFC_NUM_VS_CBACKS; i++) { 60 /* find an empty spot to hold the callback function */ 61 if (nfc_cb.p_vs_cb[i] == NULL) { 62 nfc_cb.p_vs_cb[i] = p_cback; 63 status = NFC_STATUS_OK; 64 break; 65 } 66 } 67 } else { 68 for (i = 0; i < NFC_NUM_VS_CBACKS; i++) { 69 /* find the callback to de-register */ 70 if (nfc_cb.p_vs_cb[i] == p_cback) { 71 nfc_cb.p_vs_cb[i] = NULL; 72 status = NFC_STATUS_OK; 73 break; 74 } 75 } 76 } 77 return status; 78 } 79 80 /******************************************************************************* 81 ** 82 ** Function NFC_SendRawVsCommand 83 ** 84 ** Description This function is called to send the raw vendor specific 85 ** command to NFCC. The response from NFCC is reported to the 86 ** given tNFC_VS_CBACK. 87 ** 88 ** Parameters p_data - The command buffer 89 ** 90 ** Returns tNFC_STATUS 91 ** 92 *******************************************************************************/ 93 tNFC_STATUS NFC_SendRawVsCommand(NFC_HDR* p_data, tNFC_VS_CBACK* p_cback) { 94 /* Validate parameters */ 95 if (p_data == NULL || (p_data->len > NCI_MAX_VSC_SIZE)) { 96 LOG(ERROR) << StringPrintf("buffer offset must be >= %d", 97 NCI_VSC_MSG_HDR_SIZE); 98 if (p_data) GKI_freebuf(p_data); 99 return NFC_STATUS_INVALID_PARAM; 100 } 101 102 p_data->event = BT_EVT_TO_NFC_NCI; 103 p_data->layer_specific = NFC_WAIT_RSP_RAW_VS; 104 /* save the callback function in the BT_HDR, to receive the response */ 105 ((tNFC_NCI_VS_MSG*)p_data)->p_cback = p_cback; 106 107 nfc_ncif_check_cmd_queue(p_data); 108 return NFC_STATUS_OK; 109 } 110 111 /******************************************************************************* 112 ** 113 ** Function NFC_SendVsCommand 114 ** 115 ** Description This function is called to send the given vendor specific 116 ** command to NFCC. The response from NFCC is reported to the 117 ** given tNFC_VS_CBACK as (oid). 118 ** 119 ** Parameters oid - The opcode of the VS command. 120 ** p_data - The parameters for the VS command 121 ** 122 ** Returns tNFC_STATUS 123 ** 124 *******************************************************************************/ 125 tNFC_STATUS NFC_SendVsCommand(uint8_t oid, NFC_HDR* p_data, 126 tNFC_VS_CBACK* p_cback) { 127 tNFC_STATUS status = NFC_STATUS_OK; 128 uint8_t* pp; 129 130 /* Allow VSC with 0-length payload */ 131 if (p_data == NULL) { 132 p_data = NCI_GET_CMD_BUF(0); 133 if (p_data) { 134 p_data->offset = NCI_VSC_MSG_HDR_SIZE; 135 p_data->len = 0; 136 } 137 } 138 139 /* Validate parameters */ 140 if ((p_data == NULL) || (p_data->offset < NCI_VSC_MSG_HDR_SIZE) || 141 (p_data->len > NCI_MAX_VSC_SIZE)) { 142 LOG(ERROR) << StringPrintf("buffer offset must be >= %d", 143 NCI_VSC_MSG_HDR_SIZE); 144 if (p_data) GKI_freebuf(p_data); 145 return NFC_STATUS_INVALID_PARAM; 146 } 147 148 p_data->event = BT_EVT_TO_NFC_NCI; 149 p_data->layer_specific = NFC_WAIT_RSP_VSC; 150 /* save the callback function in the NFC_HDR, to receive the response */ 151 ((tNFC_NCI_VS_MSG*)p_data)->p_cback = p_cback; 152 153 p_data->offset -= NCI_MSG_HDR_SIZE; 154 pp = (uint8_t*)(p_data + 1) + p_data->offset; 155 NCI_MSG_BLD_HDR0(pp, NCI_MT_CMD, NCI_GID_PROP); 156 NCI_MSG_BLD_HDR1(pp, oid); 157 *pp = (uint8_t)p_data->len; 158 p_data->len += NCI_MSG_HDR_SIZE; 159 nfc_ncif_check_cmd_queue(p_data); 160 return status; 161 } 162