1 /*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "sync.h"
18 #include <utils/Log.h>
19 #include "nan.h"
20 #include "wifi_hal.h"
21 #include "nan_i.h"
22 #include "nancommand.h"
23
24
isNanResponse()25 int NanCommand::isNanResponse()
26 {
27 if (mNanVendorEvent == NULL) {
28 ALOGE("NULL check failed");
29 return WIFI_ERROR_INVALID_ARGS;
30 }
31
32 NanMsgHeader *pHeader = (NanMsgHeader *)mNanVendorEvent;
33
34 switch (pHeader->msgId) {
35 case NAN_MSG_ID_ERROR_RSP:
36 case NAN_MSG_ID_CONFIGURATION_RSP:
37 case NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_RSP:
38 case NAN_MSG_ID_PUBLISH_SERVICE_RSP:
39 case NAN_MSG_ID_SUBSCRIBE_SERVICE_RSP:
40 case NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_RSP:
41 case NAN_MSG_ID_TRANSMIT_FOLLOWUP_RSP:
42 case NAN_MSG_ID_STATS_RSP:
43 case NAN_MSG_ID_ENABLE_RSP:
44 case NAN_MSG_ID_DISABLE_RSP:
45 case NAN_MSG_ID_TCA_RSP:
46 #ifdef NAN_2_0
47 case NAN_MSG_ID_BEACON_SDF_RSP:
48 #endif /* NAN_2_0 */
49 return 1;
50 default:
51 return 0;
52 }
53 }
54
55
getNanResponse(NanResponseMsg * pRsp)56 int NanCommand::getNanResponse(NanResponseMsg *pRsp)
57 {
58 if (mNanVendorEvent == NULL || pRsp == NULL) {
59 ALOGE("NULL check failed");
60 return WIFI_ERROR_INVALID_ARGS;
61 }
62
63 NanMsgHeader *pHeader = (NanMsgHeader *)mNanVendorEvent;
64
65 switch (pHeader->msgId) {
66 case NAN_MSG_ID_ERROR_RSP:
67 {
68 pNanErrorRspMsg pFwRsp = \
69 (pNanErrorRspMsg)mNanVendorEvent;
70 pRsp->header.handle = pFwRsp->fwHeader.handle;
71 pRsp->header.transaction_id = pFwRsp->fwHeader.transactionId;
72 pRsp->status = pFwRsp->status;
73 pRsp->value = pFwRsp->value;
74 pRsp->response_type = NAN_RESPONSE_ERROR;
75 break;
76 }
77 case NAN_MSG_ID_CONFIGURATION_RSP:
78 {
79 pNanConfigurationRspMsg pFwRsp = \
80 (pNanConfigurationRspMsg)mNanVendorEvent;
81 pRsp->header.handle = pFwRsp->fwHeader.handle;
82 pRsp->header.transaction_id = pFwRsp->fwHeader.transactionId;
83 pRsp->status = pFwRsp->status;
84 pRsp->value = pFwRsp->value;
85 pRsp->response_type = NAN_RESPONSE_CONFIG;
86 }
87 break;
88 case NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_RSP:
89 {
90 pNanPublishServiceCancelRspMsg pFwRsp = \
91 (pNanPublishServiceCancelRspMsg)mNanVendorEvent;
92 pRsp->header.handle = pFwRsp->fwHeader.handle;
93 pRsp->header.transaction_id = pFwRsp->fwHeader.transactionId;
94 pRsp->status = pFwRsp->status;
95 pRsp->value = pFwRsp->value;
96 pRsp->response_type = NAN_RESPONSE_PUBLISH_CANCEL;
97 break;
98 }
99 case NAN_MSG_ID_PUBLISH_SERVICE_RSP:
100 {
101 pNanPublishServiceRspMsg pFwRsp = \
102 (pNanPublishServiceRspMsg)mNanVendorEvent;
103 pRsp->header.handle = pFwRsp->fwHeader.handle;
104 pRsp->header.transaction_id = pFwRsp->fwHeader.transactionId;
105 pRsp->status = pFwRsp->status;
106 pRsp->value = pFwRsp->value;
107 pRsp->response_type = NAN_RESPONSE_PUBLISH;
108 break;
109 }
110 case NAN_MSG_ID_SUBSCRIBE_SERVICE_RSP:
111 {
112 pNanSubscribeServiceRspMsg pFwRsp = \
113 (pNanSubscribeServiceRspMsg)mNanVendorEvent;
114 pRsp->header.handle = pFwRsp->fwHeader.handle;
115 pRsp->header.transaction_id = pFwRsp->fwHeader.transactionId;
116 pRsp->status = pFwRsp->status;
117 pRsp->value = pFwRsp->value;
118 pRsp->response_type = NAN_RESPONSE_SUBSCRIBE;
119 }
120 break;
121 case NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_RSP:
122 {
123 pNanSubscribeServiceCancelRspMsg pFwRsp = \
124 (pNanSubscribeServiceCancelRspMsg)mNanVendorEvent;
125 pRsp->header.handle = pFwRsp->fwHeader.handle;
126 pRsp->header.transaction_id = pFwRsp->fwHeader.transactionId;
127 pRsp->status = pFwRsp->status;
128 pRsp->value = pFwRsp->value;
129 pRsp->response_type = NAN_RESPONSE_SUBSCRIBE_CANCEL;
130 break;
131 }
132 case NAN_MSG_ID_TRANSMIT_FOLLOWUP_RSP:
133 {
134 pNanTransmitFollowupRspMsg pFwRsp = \
135 (pNanTransmitFollowupRspMsg)mNanVendorEvent;
136 pRsp->header.handle = pFwRsp->fwHeader.handle;
137 pRsp->header.transaction_id = pFwRsp->fwHeader.transactionId;
138 pRsp->status = pFwRsp->status;
139 pRsp->value = pFwRsp->value;
140 pRsp->response_type = NAN_RESPONSE_TRANSMIT_FOLLOWUP;
141 break;
142 }
143 case NAN_MSG_ID_STATS_RSP:
144 {
145 pNanStatsRspMsg pFwRsp = \
146 (pNanStatsRspMsg)mNanVendorEvent;
147 pRsp->header.handle = pFwRsp->fwHeader.handle;
148 pRsp->header.transaction_id = pFwRsp->fwHeader.transactionId;
149 pRsp->status = pFwRsp->statsRspParams.status;
150 pRsp->value = pFwRsp->statsRspParams.value;
151 pRsp->response_type = NAN_RESPONSE_STATS;
152 pRsp->body.stats_response.stats_id = \
153 (NanStatsId)pFwRsp->statsRspParams.statsId;
154 ALOGI("%s: stats_id:%d",__func__,
155 pRsp->body.stats_response.stats_id);
156 u8 *pInputTlv = pFwRsp->ptlv;
157 NanTlv outputTlv;
158 memset(&outputTlv, 0, sizeof(outputTlv));
159 u16 readLen = 0;
160 int remainingLen = (mNanDataLen - \
161 (sizeof(NanMsgHeader) + sizeof(NanStatsRspParams)));
162
163 if (remainingLen > 0) {
164 readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv);
165 ALOGI("%s: Remaining Len:%d readLen:%d type:%d length:%d",
166 __func__, remainingLen, readLen, outputTlv.type,
167 outputTlv.length);
168 if (outputTlv.length <= \
169 sizeof(pRsp->body.stats_response.data)) {
170 memcpy(&pRsp->body.stats_response.data, outputTlv.value,
171 outputTlv.length);
172 hexdump((char*)&pRsp->body.stats_response.data, outputTlv.length);
173 }
174 else {
175 ALOGE("%s:copying only sizeof(pRsp->body.stats_response.data):%d",
176 __func__, sizeof(pRsp->body.stats_response.data));
177 memcpy(&pRsp->body.stats_response.data, outputTlv.value,
178 sizeof(pRsp->body.stats_response.data));
179 hexdump((char*)&pRsp->body.stats_response.data,
180 sizeof(pRsp->body.stats_response.data));
181 }
182 }
183 else
184 ALOGI("%s: No TLV's present",__func__);
185 break;
186 }
187 case NAN_MSG_ID_ENABLE_RSP:
188 {
189 pNanEnableRspMsg pFwRsp = \
190 (pNanEnableRspMsg)mNanVendorEvent;
191 pRsp->header.handle = pFwRsp->fwHeader.handle;
192 pRsp->header.transaction_id = pFwRsp->fwHeader.transactionId;
193 pRsp->status = pFwRsp->status;
194 pRsp->value = pFwRsp->value;
195 pRsp->response_type = NAN_RESPONSE_ENABLED;
196 break;
197 }
198 case NAN_MSG_ID_DISABLE_RSP:
199 {
200 pNanDisableRspMsg pFwRsp = \
201 (pNanDisableRspMsg)mNanVendorEvent;
202 pRsp->header.handle = pFwRsp->fwHeader.handle;
203 pRsp->header.transaction_id = pFwRsp->fwHeader.transactionId;
204 pRsp->status = pFwRsp->status;
205 pRsp->value = 0;
206 pRsp->response_type = NAN_RESPONSE_DISABLED;
207 break;
208 }
209 case NAN_MSG_ID_TCA_RSP:
210 {
211 pNanTcaRspMsg pFwRsp = \
212 (pNanTcaRspMsg)mNanVendorEvent;
213 pRsp->header.handle = pFwRsp->fwHeader.handle;
214 pRsp->header.transaction_id = pFwRsp->fwHeader.transactionId;
215 pRsp->status = pFwRsp->status;
216 pRsp->value = pFwRsp->value;
217 pRsp->response_type = NAN_RESPONSE_TCA;
218 break;
219 }
220 #ifdef NAN_2_0
221 case NAN_MSG_ID_BEACON_SDF_RSP:
222 {
223 pNanBeaconSdfPayloadRspMsg pFwRsp = \
224 (pNanBeaconSdfPayloadRspMsg)mNanVendorEvent;
225 pRsp->header.handle = pFwRsp->fwHeader.handle;
226 pRsp->header.transaction_id = pFwRsp->fwHeader.transactionId;
227 pRsp->status = pFwRsp->status;
228 pRsp->value = 0;
229 pRsp->response_type = NAN_RESPONSE_BEACON_SDF_PAYLOAD;
230 break;
231 }
232 #endif /* NAN_2_0 */
233 default:
234 return -1;
235 }
236 return 0;
237 }
238
handleNanResponse()239 int NanCommand::handleNanResponse()
240 {
241 //parse the data and call
242 //the response callback handler with the populated
243 //NanResponseMsg
244 NanResponseMsg rsp_data;
245 int ret;
246
247 ALOGV("handleNanResponse called %p", this);
248 memset(&rsp_data, 0, sizeof(rsp_data));
249 //get the rsp_data
250 ret = getNanResponse(&rsp_data);
251
252 ALOGI("handleNanResponse ret:%d status:%u value:%u response_type:%u",
253 ret, rsp_data.status, rsp_data.value, rsp_data.response_type);
254 if (ret == 0 && (rsp_data.response_type == NAN_RESPONSE_STATS) &&
255 (mStaParam != NULL) &&
256 (rsp_data.body.stats_response.stats_id == NAN_STATS_ID_DE_TIMING_SYNC)) {
257 /*
258 Fill the staParam with appropriate values and return from here.
259 No need to call NotifyResponse as the request is for getting the
260 STA response
261 */
262 NanSyncStats *pSyncStats = &rsp_data.body.stats_response.data.sync_stats;
263 mStaParam->master_rank = pSyncStats->myRank;
264 mStaParam->master_pref = (pSyncStats->myRank & 0xFF00000000000000) >> 56;
265 mStaParam->random_factor = (pSyncStats->myRank & 0x00FF000000000000) >> 48;
266 mStaParam->hop_count = pSyncStats->currAmHopCount;
267 mStaParam->beacon_transmit_time = pSyncStats->currAmBTT;
268
269 return ret;
270 }
271 //Call the NotifyResponse Handler
272 if (ret == 0 && mHandler.NotifyResponse) {
273 (*mHandler.NotifyResponse)(&rsp_data, mUserData);
274 }
275 return ret;
276 }
277