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 *******************************************************************************/
NFC_RegVSCback(bool is_register,tNFC_VS_CBACK * p_cback)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] == nullptr) {
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] = nullptr;
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 *******************************************************************************/
NFC_SendRawVsCommand(NFC_HDR * p_data,tNFC_VS_CBACK * p_cback)93 tNFC_STATUS NFC_SendRawVsCommand(NFC_HDR* p_data, tNFC_VS_CBACK* p_cback) {
94 /* Validate parameters */
95 if (p_data == nullptr || (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 *******************************************************************************/
NFC_SendVsCommand(uint8_t oid,NFC_HDR * p_data,tNFC_VS_CBACK * p_cback)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 == nullptr) {
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 == nullptr) || (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