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 #include "gki.h" 28 #include "nfc_target.h" 29 30 #include "nfc_int.h" 31 32 /**************************************************************************** 33 ** Declarations 34 ****************************************************************************/ 35 36 /******************************************************************************* 37 ** 38 ** Function NFC_RegVSCback 39 ** 40 ** Description This function is called to register or de-register a 41 ** callback function to receive Proprietary NCI response and 42 ** notification events. The maximum number of callback 43 ** functions allowed is NFC_NUM_VS_CBACKS 44 ** 45 ** Returns tNFC_STATUS 46 ** 47 *******************************************************************************/ 48 tNFC_STATUS NFC_RegVSCback(bool is_register, tNFC_VS_CBACK* p_cback) { 49 tNFC_STATUS status = NFC_STATUS_FAILED; 50 int i; 51 52 if (is_register) { 53 for (i = 0; i < NFC_NUM_VS_CBACKS; i++) { 54 /* find an empty spot to hold the callback function */ 55 if (nfc_cb.p_vs_cb[i] == NULL) { 56 nfc_cb.p_vs_cb[i] = p_cback; 57 status = NFC_STATUS_OK; 58 break; 59 } 60 } 61 } else { 62 for (i = 0; i < NFC_NUM_VS_CBACKS; i++) { 63 /* find the callback to de-register */ 64 if (nfc_cb.p_vs_cb[i] == p_cback) { 65 nfc_cb.p_vs_cb[i] = NULL; 66 status = NFC_STATUS_OK; 67 break; 68 } 69 } 70 } 71 return status; 72 } 73 74 /******************************************************************************* 75 ** 76 ** Function NFC_SendVsCommand 77 ** 78 ** Description This function is called to send the given vendor specific 79 ** command to NFCC. The response from NFCC is reported to the 80 ** given tNFC_VS_CBACK as (oid). 81 ** 82 ** Parameters oid - The opcode of the VS command. 83 ** p_data - The parameters for the VS command 84 ** 85 ** Returns tNFC_STATUS 86 ** 87 *******************************************************************************/ 88 tNFC_STATUS NFC_SendVsCommand(uint8_t oid, NFC_HDR* p_data, 89 tNFC_VS_CBACK* p_cback) { 90 tNFC_STATUS status = NFC_STATUS_OK; 91 uint8_t* pp; 92 93 /* Allow VSC with 0-length payload */ 94 if (p_data == NULL) { 95 p_data = NCI_GET_CMD_BUF(0); 96 if (p_data) { 97 p_data->offset = NCI_VSC_MSG_HDR_SIZE; 98 p_data->len = 0; 99 } 100 } 101 102 /* Validate parameters */ 103 if ((p_data == NULL) || (p_data->offset < NCI_VSC_MSG_HDR_SIZE) || 104 (p_data->len > NCI_MAX_VSC_SIZE)) { 105 NFC_TRACE_ERROR1("buffer offset must be >= %d", NCI_VSC_MSG_HDR_SIZE); 106 if (p_data) GKI_freebuf(p_data); 107 return NFC_STATUS_INVALID_PARAM; 108 } 109 110 p_data->event = BT_EVT_TO_NFC_NCI; 111 p_data->layer_specific = NFC_WAIT_RSP_VSC; 112 /* save the callback function in the NFC_HDR, to receive the response */ 113 ((tNFC_NCI_VS_MSG*)p_data)->p_cback = p_cback; 114 115 p_data->offset -= NCI_MSG_HDR_SIZE; 116 pp = (uint8_t*)(p_data + 1) + p_data->offset; 117 NCI_MSG_BLD_HDR0(pp, NCI_MT_CMD, NCI_GID_PROP); 118 NCI_MSG_BLD_HDR1(pp, oid); 119 *pp = (uint8_t)p_data->len; 120 p_data->len += NCI_MSG_HDR_SIZE; 121 nfc_ncif_check_cmd_queue(p_data); 122 return status; 123 } 124