• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <errno.h>
20 #include "nan.h"
21 #include "wifi_hal.h"
22 #include "nan_i.h"
23 #include "nancommand.h"
24 #include <errno.h>
25 
26 #define NAN_TERMINATED_BEGINNING_OFFSET       8192
27 
28 //Function which calls the necessaryIndication callback
29 //based on the indication type
handleNanIndication()30 int NanCommand::handleNanIndication()
31 {
32     //Based on the message_id in the header determine the Indication type
33     //and call the necessary callback handler
34     u16 msg_id;
35     int res = 0;
36 
37     ALOGI("handleNanIndication called %p", this);
38     msg_id = getIndicationType();
39 
40     ALOGI("handleNanIndication msg_id:%u", msg_id);
41     switch (msg_id) {
42     case NAN_INDICATION_PUBLISH_REPLIED:
43         NanPublishRepliedInd publishRepliedInd;
44         memset(&publishRepliedInd, 0, sizeof(publishRepliedInd));
45         res = getNanPublishReplied(&publishRepliedInd);
46         if (!res && mHandler.EventPublishReplied) {
47             (*mHandler.EventPublishReplied)(&publishRepliedInd,
48                                             mUserData);
49         }
50         break;
51 
52     case NAN_INDICATION_PUBLISH_TERMINATED:
53         NanPublishTerminatedInd publishTerminatedInd;
54         memset(&publishTerminatedInd, 0, sizeof(publishTerminatedInd));
55         res = getNanPublishTerminated(&publishTerminatedInd);
56         if (!res && mHandler.EventPublishTerminated) {
57             (*mHandler.EventPublishTerminated)(&publishTerminatedInd,
58                                                mUserData);
59         }
60         break;
61 
62     case NAN_INDICATION_MATCH:
63         NanMatchInd matchInd;
64         memset(&matchInd, 0, sizeof(matchInd));
65         res = getNanMatch(&matchInd);
66         if (!res && mHandler.EventMatch) {
67             (*mHandler.EventMatch)(&matchInd, mUserData);
68         }
69         break;
70 
71     case NAN_INDICATION_UNMATCH:
72         NanUnmatchInd unMatchInd;
73         memset(&unMatchInd, 0, sizeof(unMatchInd));
74         res = getNanUnMatch(&unMatchInd);
75         if (!res && mHandler.EventUnMatch) {
76             (*mHandler.EventUnMatch)(&unMatchInd, mUserData);
77         }
78         break;
79 
80     case NAN_INDICATION_SUBSCRIBE_TERMINATED:
81         NanSubscribeTerminatedInd subscribeTerminatedInd;
82         memset(&subscribeTerminatedInd, 0, sizeof(subscribeTerminatedInd));
83         res = getNanSubscribeTerminated(&subscribeTerminatedInd);
84         if (!res && mHandler.EventSubscribeTerminated) {
85             (*mHandler.EventSubscribeTerminated)(&subscribeTerminatedInd,
86                                                  mUserData);
87         }
88         break;
89 
90     case NAN_INDICATION_DE_EVENT:
91         NanDiscEngEventInd discEngEventInd;
92         memset(&discEngEventInd, 0, sizeof(discEngEventInd));
93         res = getNanDiscEngEvent(&discEngEventInd);
94         if (!res && mHandler.EventDiscEngEvent) {
95             (*mHandler.EventDiscEngEvent)(&discEngEventInd,
96                                           mUserData);
97         }
98         break;
99 
100     case NAN_INDICATION_FOLLOWUP:
101         NanFollowupInd followupInd;
102         memset(&followupInd, 0, sizeof(followupInd));
103         res = getNanFollowup(&followupInd);
104         if (!res && mHandler.EventFollowup) {
105             (*mHandler.EventFollowup)(&followupInd,
106                                       mUserData);
107         }
108         break;
109 
110     case NAN_INDICATION_DISABLED:
111         NanDisabledInd disabledInd;
112         memset(&disabledInd, 0, sizeof(disabledInd));
113         res = getNanDisabled(&disabledInd);
114         if (!res && mHandler.EventDisabled) {
115             (*mHandler.EventDisabled)(&disabledInd,
116                                       mUserData);
117         }
118         break;
119 
120     case NAN_INDICATION_TCA:
121         NanTCAInd tcaInd;
122         memset(&tcaInd, 0, sizeof(tcaInd));
123         res = getNanTca(&tcaInd);
124         if (!res && mHandler.EventTca) {
125             (*mHandler.EventTca)(&tcaInd,
126                                  mUserData);
127         }
128         break;
129 
130     case NAN_INDICATION_BEACON_SDF_PAYLOAD:
131         NanBeaconSdfPayloadInd beaconSdfPayloadInd;
132         memset(&beaconSdfPayloadInd, 0, sizeof(beaconSdfPayloadInd));
133         res = getNanBeaconSdfPayload(&beaconSdfPayloadInd);
134         if (!res && mHandler.EventSdfPayload) {
135             (*mHandler.EventSdfPayload)(&beaconSdfPayloadInd,
136                                         mUserData);
137         }
138         break;
139 
140     default:
141         ALOGE("handleNanIndication error invalid msg_id:%u", msg_id);
142         res = (int)WIFI_ERROR_INVALID_REQUEST_ID;
143         break;
144     }
145     return res;
146 }
147 
148 //Function which will return the Nan Indication type based on
149 //the initial few bytes of mNanVendorEvent
getIndicationType()150 NanIndicationType NanCommand::getIndicationType()
151 {
152     if (mNanVendorEvent == NULL) {
153         ALOGE("%s: Invalid argument mNanVendorEvent:%p",
154               __func__, mNanVendorEvent);
155         return NAN_INDICATION_UNKNOWN;
156     }
157 
158     NanMsgHeader *pHeader = (NanMsgHeader *)mNanVendorEvent;
159 
160     switch (pHeader->msgId) {
161     case NAN_MSG_ID_PUBLISH_REPLIED_IND:
162         return NAN_INDICATION_PUBLISH_REPLIED;
163     case NAN_MSG_ID_PUBLISH_TERMINATED_IND:
164         return NAN_INDICATION_PUBLISH_TERMINATED;
165     case NAN_MSG_ID_MATCH_IND:
166         return NAN_INDICATION_MATCH;
167     case NAN_MSG_ID_UNMATCH_IND:
168         return NAN_INDICATION_UNMATCH;
169     case NAN_MSG_ID_FOLLOWUP_IND:
170         return NAN_INDICATION_FOLLOWUP;
171     case NAN_MSG_ID_SUBSCRIBE_TERMINATED_IND:
172         return NAN_INDICATION_SUBSCRIBE_TERMINATED;
173     case  NAN_MSG_ID_DE_EVENT_IND:
174         return NAN_INDICATION_DE_EVENT;
175     case NAN_MSG_ID_DISABLE_IND:
176         return NAN_INDICATION_DISABLED;
177     case NAN_MSG_ID_TCA_IND:
178         return NAN_INDICATION_TCA;
179 #ifdef NAN_2_0
180     case NAN_MSG_ID_BEACON_SDF_IND:
181         return NAN_INDICATION_BEACON_SDF_PAYLOAD;
182 #endif /* NAN_2_0 */
183     default:
184         return NAN_INDICATION_UNKNOWN;
185     }
186 }
187 
getNanPublishReplied(NanPublishRepliedInd * event)188 int NanCommand::getNanPublishReplied(NanPublishRepliedInd *event)
189 {
190     if (event == NULL || mNanVendorEvent == NULL) {
191         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
192               __func__, event, mNanVendorEvent);
193         return WIFI_ERROR_INVALID_ARGS;
194     }
195 
196     pNanPublishRepliedIndMsg pRsp = (pNanPublishRepliedIndMsg)mNanVendorEvent;
197     event->header.handle = pRsp->fwHeader.handle;
198     event->header.transaction_id = pRsp->fwHeader.transactionId;
199 #ifndef NAN_2_0
200     memcpy(event->addr, pRsp->publishRepliedIndParams.macAddr, sizeof(event->addr));
201 #else /* NAN_2_0 */
202     event->rssi_value = 0;
203     u8 *pInputTlv = pRsp->ptlv;
204     NanTlv outputTlv;
205     u16 readLen = 0;
206     int ret = 0;
207     int remainingLen = (mNanDataLen - \
208         (sizeof(NanMsgHeader)));
209 
210     //Has NAN Mac address mandatory, received RSSI value optional
211     //POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE
212     //POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE
213     //NAN_FURTHER_AVAILABILITY_MAP
214     //NAN_CLUSTER_ATTRIBUTE
215     if (remainingLen <= 0) {
216         ALOGI("%s: No TLV's present",__func__);
217         return WIFI_SUCCESS;
218     }
219     ALOGI("%s: TLV remaining Len:%d",__func__, remainingLen);
220     while ((remainingLen > 0) &&
221            (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
222         ALOGI("%s: Remaining Len:%d readLen:%d type:%d length:%d",
223               __func__, remainingLen, readLen, outputTlv.type,
224               outputTlv.length);
225         switch (outputTlv.type) {
226         case NAN_TLV_TYPE_MAC_ADDRESS:
227             if (outputTlv.length > sizeof(event->addr)) {
228                 outputTlv.length = sizeof(event->addr);
229             }
230             memcpy(event->addr, outputTlv.value, outputTlv.length);
231             break;
232         case NAN_TLV_TYPE_RECEIVED_RSSI_VALUE:
233             if (outputTlv.length > sizeof(event->rssi_value)) {
234                 outputTlv.length = sizeof(event->rssi_value);
235             }
236             memcpy(&event->rssi_value, outputTlv.value,
237                    outputTlv.length);
238             break;
239         case NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE:
240             if (outputTlv.length != sizeof(u32)) {
241                 ALOGE("NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE"
242                       "Incorrect size:%d expecting %d", outputTlv.length,
243                       sizeof(u32));
244                 break;
245             }
246             event->is_conn_capability_valid = 1;
247             /* Populate conn_capability from received TLV */
248             getNanReceivePostConnectivityCapabilityVal(outputTlv.value,
249                                                        &event->conn_capability);
250             break;
251         case NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE:
252             /* Populate receive discovery attribute from
253                received TLV */
254             ret = getNanReceivePostDiscoveryVal(outputTlv.value,
255                                                     outputTlv.length,
256                                                     &event->discovery_attr);
257             if (ret == 0) {
258                 event->is_discovery_attr_valid = 1;
259             }
260             else {
261                 ALOGE("NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE"
262                       "Incorrect");
263             }
264             break;
265         case NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP:
266             /* Populate further availability bitmap from
267                received TLV */
268             ret = getNanFurtherAvailabilityMap(outputTlv.value,
269                                                outputTlv.length,
270                                                &event->fam);
271             if (ret == 0) {
272                 event->is_fam_valid = 1;
273             }
274             else {
275                 ALOGE("NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP"
276                       "Incorrect");
277             }
278             break;
279         case NAN_TLV_TYPE_CLUSTER_ATTIBUTE:
280             if (outputTlv.length > sizeof(event->cluster_attribute)) {
281                 outputTlv.length = sizeof(event->cluster_attribute);
282             }
283             memcpy(event->cluster_attribute,
284                    outputTlv.value, outputTlv.length);
285             event->cluster_attribute_len = outputTlv.length;
286             break;
287         default:
288             ALOGI("Unknown TLV type skipped");
289             break;
290         }
291         remainingLen -= readLen;
292         pInputTlv += readLen;
293         memset(&outputTlv, 0, sizeof(outputTlv));
294     }
295 #endif /* NAN_2_0 */
296     return WIFI_SUCCESS;
297 }
298 
299 
getNanPublishTerminated(NanPublishTerminatedInd * event)300 int NanCommand::getNanPublishTerminated(NanPublishTerminatedInd *event)
301 {
302     if (event == NULL || mNanVendorEvent == NULL) {
303         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
304               __func__, event, mNanVendorEvent);
305         return WIFI_ERROR_INVALID_ARGS;
306     }
307 
308     pNanPublishTerminatedIndMsg pRsp = (pNanPublishTerminatedIndMsg)mNanVendorEvent;
309     event->header.handle = pRsp->fwHeader.handle;
310     event->header.transaction_id = pRsp->fwHeader.transactionId;
311 #ifdef NAN_2_0
312     pRsp->reason -= NAN_TERMINATED_BEGINNING_OFFSET;
313 #endif /* NAN_2_0 */
314     event->reason = (NanTerminatedStatus)pRsp->reason;
315     return WIFI_SUCCESS;
316 }
317 
getNanMatch(NanMatchInd * event)318 int NanCommand::getNanMatch(NanMatchInd *event)
319 {
320     if (event == NULL || mNanVendorEvent == NULL) {
321         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
322               __func__, event, mNanVendorEvent);
323         return WIFI_ERROR_INVALID_ARGS;
324     }
325 
326     pNanMatchIndMsg pRsp = (pNanMatchIndMsg)mNanVendorEvent;
327     event->header.handle = pRsp->fwHeader.handle;
328     event->header.transaction_id = pRsp->fwHeader.transactionId;
329     event->match_handle = pRsp->matchIndParams.matchHandle;
330 #ifndef NAN_2_0
331     memcpy(event->addr, pRsp->matchIndParams.macAddr, sizeof(event->addr));
332 #else /* NAN_2_0 */
333     event->match_occured_flag = pRsp->matchIndParams.matchOccuredFlag;
334     event->out_of_resource_flag = pRsp->matchIndParams.outOfResourceFlag;
335 #endif /* NAN_2_0 */
336 
337     u8 *pInputTlv = pRsp->ptlv;
338     NanTlv outputTlv;
339     u16 readLen = 0;
340     int remainingLen = (mNanDataLen - \
341         (sizeof(NanMsgHeader) + sizeof(NanMatchIndParams)));
342     int ret = 0;
343 
344     //Has SDF match filter and service specific info TLV
345     if (remainingLen <= 0) {
346         ALOGI("%s: No TLV's present",__func__);
347         return WIFI_SUCCESS;
348     }
349     ALOGI("%s: TLV remaining Len:%d",__func__, remainingLen);
350     while ((remainingLen > 0) &&
351            (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
352         ALOGI("%s: Remaining Len:%d readLen:%d type:%d length:%d",
353               __func__, remainingLen, readLen, outputTlv.type,
354               outputTlv.length);
355         switch (outputTlv.type) {
356         case NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO:
357             if (outputTlv.length > NAN_MAX_SERVICE_NAME_LEN) {
358                 outputTlv.length = NAN_MAX_SERVICE_NAME_LEN;
359             }
360             event->service_specific_info_len = outputTlv.length;
361             memcpy(event->service_specific_info, outputTlv.value,
362                    outputTlv.length);
363             break;
364         case NAN_TLV_TYPE_SDF_MATCH_FILTER:
365             if (outputTlv.length > NAN_MAX_MATCH_FILTER_LEN) {
366                 outputTlv.length = NAN_MAX_MATCH_FILTER_LEN;
367             }
368             event->sdf_match_filter_len = outputTlv.length;
369             memcpy(event->sdf_match_filter, outputTlv.value,
370                    outputTlv.length);
371             break;
372 #ifdef NAN_2_0
373         case NAN_TLV_TYPE_MAC_ADDRESS:
374             if (outputTlv.length > sizeof(event->addr)) {
375                 outputTlv.length = sizeof(event->addr);
376             }
377             memcpy(event->addr, outputTlv.value, outputTlv.length);
378             break;
379         case NAN_TLV_TYPE_RECEIVED_RSSI_VALUE:
380             if (outputTlv.length > sizeof(event->rssi_value)) {
381                 outputTlv.length = sizeof(event->rssi_value);
382             }
383             memcpy(&event->rssi_value, outputTlv.value,
384                    outputTlv.length);
385             break;
386         case NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE:
387             if (outputTlv.length != sizeof(u32)) {
388                 ALOGE("NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE"
389                       "Incorrect size:%d expecting %d", outputTlv.length,
390                       sizeof(u32));
391                 break;
392             }
393             event->is_conn_capability_valid = 1;
394             /* Populate conn_capability from received TLV */
395             getNanReceivePostConnectivityCapabilityVal(outputTlv.value,
396                                                        &event->conn_capability);
397             break;
398         case NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE:
399             /* Populate receive discovery attribute from
400                received TLV */
401             ret = getNanReceivePostDiscoveryVal(outputTlv.value,
402                                                     outputTlv.length,
403                                                     &event->discovery_attr);
404             if (ret == 0) {
405                 event->is_discovery_attr_valid = 1;
406             }
407             else {
408                 ALOGE("NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE"
409                       "Incorrect");
410             }
411             break;
412         case NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP:
413             /* Populate further availability bitmap from
414                received TLV */
415             ret = getNanFurtherAvailabilityMap(outputTlv.value,
416                                                outputTlv.length,
417                                                &event->fam);
418             if (ret == 0) {
419                 event->is_fam_valid = 1;
420             }
421             else {
422                 ALOGE("NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP"
423                       "Incorrect");
424             }
425             break;
426         case NAN_TLV_TYPE_CLUSTER_ATTIBUTE:
427             if (outputTlv.length > sizeof(event->cluster_attribute)) {
428                 outputTlv.length = sizeof(event->cluster_attribute);
429             }
430             memcpy(event->cluster_attribute,
431                    outputTlv.value, outputTlv.length);
432             event->cluster_attribute_len = outputTlv.length;
433             break;
434 #endif /* NAN_2_0 */
435         default:
436             ALOGI("Unknown TLV type skipped");
437             break;
438         }
439         remainingLen -= readLen;
440         pInputTlv += readLen;
441         memset(&outputTlv, 0, sizeof(outputTlv));
442     }
443     return WIFI_SUCCESS;
444 }
445 
getNanUnMatch(NanUnmatchInd * event)446 int NanCommand::getNanUnMatch(NanUnmatchInd *event)
447 {
448     if (event == NULL || mNanVendorEvent == NULL) {
449         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
450               __func__, event, mNanVendorEvent);
451         return WIFI_ERROR_INVALID_ARGS;
452     }
453 
454     pNanUnmatchIndMsg pRsp = (pNanUnmatchIndMsg)mNanVendorEvent;
455     event->header.handle = pRsp->fwHeader.handle;
456     event->header.transaction_id = pRsp->fwHeader.transactionId;
457     event->match_handle = pRsp->unmatchIndParams.matchHandle;
458     return WIFI_SUCCESS;
459 }
460 
getNanSubscribeTerminated(NanSubscribeTerminatedInd * event)461 int NanCommand::getNanSubscribeTerminated(NanSubscribeTerminatedInd *event)
462 {
463     if (event == NULL || mNanVendorEvent == NULL) {
464         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
465               __func__, event, mNanVendorEvent);
466         return WIFI_ERROR_INVALID_ARGS;
467     }
468 
469     pNanSubscribeTerminatedIndMsg pRsp = (pNanSubscribeTerminatedIndMsg)mNanVendorEvent;
470     event->header.handle = pRsp->fwHeader.handle;
471     event->header.transaction_id = pRsp->fwHeader.transactionId;
472 #ifdef NAN_2_0
473     pRsp->reason -= NAN_TERMINATED_BEGINNING_OFFSET;
474 #endif /* NAN_2_0 */
475     event->reason = (NanTerminatedStatus)pRsp->reason;
476     return WIFI_SUCCESS;
477 }
478 
getNanFollowup(NanFollowupInd * event)479 int NanCommand::getNanFollowup(NanFollowupInd *event)
480 {
481     if (event == NULL || mNanVendorEvent == NULL) {
482         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
483               __func__, event, mNanVendorEvent);
484         return WIFI_ERROR_INVALID_ARGS;
485     }
486 
487     pNanFollowupIndMsg pRsp = (pNanFollowupIndMsg)mNanVendorEvent;
488     event->header.handle = pRsp->fwHeader.handle;
489     event->header.transaction_id = pRsp->fwHeader.transactionId;
490 #ifndef NAN_2_0
491     memcpy(event->addr, pRsp->followupIndParams.macAddr, sizeof(event->addr));
492 #else /* NAN_2_0*/
493     event->match_handle = pRsp->followupIndParams.matchHandle;
494 #endif
495     event->dw_or_faw = pRsp->followupIndParams.window;
496 
497     u8 *pInputTlv = pRsp->ptlv;
498     NanTlv outputTlv;
499     u16 readLen = 0;
500     int remainingLen = (mNanDataLen -  \
501         (sizeof(NanMsgHeader) + sizeof(NanFollowupIndParams)));
502 
503     //Has service specific info and extended service specific info TLV
504     if (remainingLen <= 0) {
505         ALOGI("%s: No TLV's present",__func__);
506         return WIFI_SUCCESS;
507     }
508     ALOGI("%s: TLV remaining Len:%d",__func__, remainingLen);
509     while ((remainingLen > 0) &&
510            (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
511         ALOGI("%s: Remaining Len:%d readLen:%d type:%d length:%d",
512               __func__, remainingLen, readLen, outputTlv.type,
513               outputTlv.length);
514         switch (outputTlv.type) {
515         case NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO:
516         case NAN_TLV_TYPE_EXT_SERVICE_SPECIFIC_INFO:
517             if (outputTlv.length > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
518                 outputTlv.length = NAN_MAX_SERVICE_SPECIFIC_INFO_LEN;
519             }
520             event->service_specific_info_len = outputTlv.length;
521             memcpy(event->service_specific_info, outputTlv.value,
522                    outputTlv.length);
523             break;
524 #ifdef NAN_2_0
525         case NAN_TLV_TYPE_MAC_ADDRESS:
526             if (outputTlv.length > sizeof(event->addr)) {
527                 outputTlv.length = sizeof(event->addr);
528             }
529             memcpy(event->addr, outputTlv.value, outputTlv.length);
530             break;
531 #endif /* NAN_2_0 */
532         default:
533             ALOGI("Unknown TLV type skipped");
534             break;
535         }
536         remainingLen -= readLen;
537         pInputTlv += readLen;
538         memset(&outputTlv, 0, sizeof(outputTlv));
539     }
540     return WIFI_SUCCESS;
541 }
542 
getNanDiscEngEvent(NanDiscEngEventInd * event)543 int NanCommand::getNanDiscEngEvent(NanDiscEngEventInd *event)
544 {
545     if (event == NULL || mNanVendorEvent == NULL) {
546         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
547               __func__, event, mNanVendorEvent);
548         return WIFI_ERROR_INVALID_ARGS;
549     }
550 
551     pNanEventIndMsg pRsp = (pNanEventIndMsg)mNanVendorEvent;
552     event->header.handle = pRsp->fwHeader.handle;
553     event->header.transaction_id = pRsp->fwHeader.transactionId;
554 #ifndef NAN_2_0
555     event->event_id = (NanEventId)pRsp->eventIndParams.eventId;
556 #endif /* NAN_2_0 */
557     memset(&event->data, 0, sizeof(event->data));
558 
559     u8 *pInputTlv = pRsp->ptlv;
560     NanTlv outputTlv;
561     u16 readLen = 0;
562 #ifndef NAN_2_0
563     int remainingLen = (mNanDataLen -  \
564         (sizeof(NanMsgHeader) + sizeof(NanEventIndParams)));
565 #else /* NAN_2_0 */
566     int remainingLen = (mNanDataLen -  \
567         (sizeof(NanMsgHeader)));
568 #endif /* NAN_2_0 */
569 
570     //Has Self-STA Mac TLV
571     if (remainingLen <= 0) {
572         ALOGI("%s: No TLV's present",__func__);
573         return WIFI_SUCCESS;
574     }
575 
576     ALOGI("%s: TLV remaining Len:%d event_id:%d",__func__,
577           remainingLen, event->event_id);
578     while ((remainingLen > 0) &&
579            (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
580         ALOGI("%s: Remaining Len:%d readLen:%d type:%d length:%d",
581               __func__, remainingLen, readLen, outputTlv.type,
582               outputTlv.length);
583 #ifdef NAN_2_0
584         event->event_id = (NanEventId)outputTlv.type;
585 #endif /* NAN_2_0 */
586         //Here we should check on the event_id
587         switch (event->event_id) {
588         case NAN_EVENT_ID_STA_MAC_ADDR:
589             if (outputTlv.length > NAN_MAC_ADDR_LEN) {
590                 ALOGI("%s: Reading only first %d bytes of TLV",
591                       __func__, NAN_MAC_ADDR_LEN);
592                 outputTlv.length = NAN_MAC_ADDR_LEN;
593             }
594             memcpy(event->data.mac_addr.addr, outputTlv.value,
595                    outputTlv.length);
596             break;
597         case NAN_EVENT_ID_STARTED_CLUSTER:
598         case NAN_EVENT_ID_JOINED_CLUSTER:
599             if (outputTlv.length > NAN_MAC_ADDR_LEN) {
600                 ALOGI("%s: Reading only first %d bytes of TLV",
601                       __func__, NAN_MAC_ADDR_LEN);
602                 outputTlv.length = NAN_MAC_ADDR_LEN;
603             }
604             memcpy(event->data.cluster.addr, outputTlv.value,
605                    outputTlv.length);
606             break;
607         default:
608             ALOGI("Unhandled eventId:%d", event->event_id);
609             break;
610         }
611         remainingLen -= readLen;
612         pInputTlv += readLen;
613         memset(&outputTlv,0, sizeof(outputTlv));
614     }
615     return WIFI_SUCCESS;
616 }
617 
getNanDisabled(NanDisabledInd * event)618 int NanCommand::getNanDisabled(NanDisabledInd *event)
619 {
620     if (event == NULL || mNanVendorEvent == NULL) {
621         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
622               __func__, event, mNanVendorEvent);
623         return WIFI_ERROR_INVALID_ARGS;
624     }
625 
626     pNanDisableIndMsg pRsp = (pNanDisableIndMsg)mNanVendorEvent;
627     event->header.handle = pRsp->fwHeader.handle;
628     event->header.transaction_id = pRsp->fwHeader.transactionId;
629     event->reason = (NanStatusType)pRsp->reason;
630     return WIFI_SUCCESS;
631 
632 }
633 
getNanTca(NanTCAInd * event)634 int NanCommand::getNanTca(NanTCAInd *event)
635 {
636     if (event == NULL || mNanVendorEvent == NULL) {
637         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
638               __func__, event, mNanVendorEvent);
639         return WIFI_ERROR_INVALID_ARGS;
640     }
641 
642     pNanTcaIndMsg pRsp = (pNanTcaIndMsg)mNanVendorEvent;
643     event->header.handle = pRsp->fwHeader.handle;
644     event->header.transaction_id = pRsp->fwHeader.transactionId;
645     memset(&event->data, 0, sizeof(event->data));
646 #ifndef NAN_2_0
647     event->tca_id = (NanTcaId)pRsp->tcaIndParams.tcaId;
648 #else /* NAN_2_0 */
649     event->tca_id = (NanTcaId)0;
650 #endif /* NAN_2_0 */
651 
652     u8 *pInputTlv = pRsp->ptlv;
653     NanTlv outputTlv;
654     u16 readLen = 0;
655 #ifndef NAN_2_0
656     int remainingLen = (mNanDataLen -  \
657         (sizeof(NanMsgHeader) + sizeof(NanTcaIndParams)));
658 #else
659     int remainingLen = (mNanDataLen -  \
660         (sizeof(NanMsgHeader)));
661 #endif
662 
663     //Has NAN_TCA_ID_CLUSTER_SIZE
664     if (remainingLen <= 0) {
665         ALOGI("%s: No TLV's present",__func__);
666         return WIFI_SUCCESS;
667     }
668 
669     ALOGI("%s: TLV remaining Len:%d tca_id:%d",__func__,
670           remainingLen, event->tca_id);
671     while ((remainingLen > 0) &&
672            (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
673         ALOGI("%s: Remaining Len:%d readLen:%d type:%d length:%d",
674               __func__, remainingLen, readLen, outputTlv.type,
675               outputTlv.length);
676         //Here we should check on the event_id
677         switch (event->tca_id) {
678         case NAN_TCA_ID_CLUSTER_SIZE:
679 #ifndef NAN_2_0
680             if (outputTlv.length > sizeof(event->data.cluster.cluster_size)) {
681                 outputTlv.length = sizeof(event->data.cluster.cluster_size);
682             }
683             memcpy(&(event->data.cluster.cluster_size), outputTlv.value,
684                    outputTlv.length);
685 #else /* NAN_2_0 */
686             if (outputTlv.length != 2 * sizeof(u32)) {
687                 ALOGE("%s: Wrong length %d in Tca Indication expecting %d bytes",
688                       __func__, outputTlv.length, 2 * sizeof(u32));
689                 break;
690             }
691             event->rising_direction_evt_flag = outputTlv.value[0] & 0x01;
692             event->falling_direction_evt_flag = (outputTlv.value[0] & 0x02) >> 1;
693             memcpy(&(event->data.cluster.cluster_size), &outputTlv.value[4],
694                    sizeof(event->data.cluster.cluster_size));
695 #endif /* NAN_2_0 */
696             break;
697         default:
698             ALOGI("Unhandled eventId:%d", event->tca_id);
699             break;
700         }
701         remainingLen -= readLen;
702         pInputTlv += readLen;
703         memset(&outputTlv,0, sizeof(outputTlv));
704     }
705     return WIFI_SUCCESS;
706 }
707 
getNanBeaconSdfPayload(NanBeaconSdfPayloadInd * event)708 int NanCommand::getNanBeaconSdfPayload(NanBeaconSdfPayloadInd *event)
709 {
710     if (event == NULL || mNanVendorEvent == NULL) {
711         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
712               __func__, event, mNanVendorEvent);
713         return WIFI_ERROR_INVALID_ARGS;
714     }
715 
716 #ifdef NAN_2_0
717     pNanBeaconSdfPayloadIndMsg pRsp = (pNanBeaconSdfPayloadIndMsg)mNanVendorEvent;
718     event->header.handle = pRsp->fwHeader.handle;
719     event->header.transaction_id = pRsp->fwHeader.transactionId;
720     memset(&event->data, 0, sizeof(event->data));
721 
722     u8 *pInputTlv = pRsp->ptlv;
723     NanTlv outputTlv;
724     u16 readLen = 0;
725     int remainingLen = (mNanDataLen -  \
726         (sizeof(NanMsgHeader)));
727 
728     //Has Mac address
729     if (remainingLen <= 0) {
730         ALOGI("%s: No TLV's present",__func__);
731         return WIFI_SUCCESS;
732     }
733 
734     ALOGI("%s: TLV remaining Len:%d",__func__, remainingLen);
735     while ((remainingLen > 0) &&
736            (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
737         ALOGI("%s: Remaining Len:%d readLen:%d type:%d length:%d",
738               __func__, remainingLen, readLen, outputTlv.type,
739               outputTlv.length);
740         //Here we should check on the event_id
741         switch (outputTlv.type) {
742         case NAN_TLV_TYPE_SELF_MAC_ADDR:
743             if (outputTlv.length > sizeof(event->addr)) {
744                 outputTlv.length = sizeof(event->addr);
745             }
746             memcpy(event->addr, outputTlv.value,
747                    outputTlv.length);
748             break;
749 
750         case NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE:
751         {
752             NanReceiveVendorSpecificAttribute* recvVsaattr = &event->vsa;
753             if (outputTlv.length < sizeof(u32)) {
754                 ALOGE("NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE"
755                       "Incorrect length:%d", outputTlv.length);
756                 break;
757             }
758             event->is_vsa_received = 1;
759             recvVsaattr->vsa_received_on = (outputTlv.value[0] >> 1) & 0x07;
760             memcpy(&recvVsaattr->vendor_oui, &outputTlv.value[1],
761                    3);
762             recvVsaattr->attr_len = outputTlv.length - 4;
763             if (recvVsaattr->attr_len > NAN_MAX_VSA_DATA_LEN) {
764                 recvVsaattr->attr_len = NAN_MAX_VSA_DATA_LEN;
765             }
766             if (recvVsaattr->attr_len) {
767                 memcpy(recvVsaattr->vsa, &outputTlv.value[4],
768                        recvVsaattr->attr_len);
769             }
770             break;
771         }
772 
773         case NAN_TLV_TYPE_BEACON_SDF_PAYLOAD_RECEIVE:
774             event->is_beacon_sdf_payload_received = 1;
775             event->data.frame_len = outputTlv.length;
776             if (event->data.frame_len > NAN_MAX_VSA_DATA_LEN) {
777                 event->data.frame_len = NAN_MAX_VSA_DATA_LEN;
778             }
779             memcpy(&event->data.frame_data, &outputTlv.value[0],
780                    event->data.frame_len);
781             break;
782 
783         default:
784             ALOGI("Unhandled TLV Type:%d", outputTlv.type);
785             break;
786         }
787         remainingLen -= readLen;
788         pInputTlv += readLen;
789         memset(&outputTlv,0, sizeof(outputTlv));
790     }
791     return WIFI_SUCCESS;
792 #else /* NAN_2_0 */
793     return WIFI_ERROR_INVALID_ARGS;
794 #endif /* NAN_2_0 */
795 }
796 
getNanReceivePostConnectivityCapabilityVal(const u8 * pInValue,NanReceivePostConnectivityCapability * pRxCapab)797 void NanCommand::getNanReceivePostConnectivityCapabilityVal(
798     const u8 *pInValue,
799     NanReceivePostConnectivityCapability *pRxCapab)
800 {
801     if (pInValue && pRxCapab) {
802         pRxCapab->is_mesh_supported = (pInValue[0] && (0x01 << 5));
803         pRxCapab->is_ibss_supported = (pInValue[0] && (0x01 << 4));
804         pRxCapab->wlan_infra_field = (pInValue[0] && (0x01 << 3));
805         pRxCapab->is_tdls_supported = (pInValue[0] && (0x01 << 2));
806         pRxCapab->is_wfds_supported = (pInValue[0] && (0x01 << 1));
807         pRxCapab->is_wfd_supported = pInValue[0] && 0x01;
808     }
809 }
810 
getNanReceivePostDiscoveryVal(const u8 * pInValue,u32 length,NanReceivePostDiscovery * pRxDisc)811 int NanCommand::getNanReceivePostDiscoveryVal(const u8 *pInValue,
812                                               u32 length,
813                                               NanReceivePostDiscovery *pRxDisc)
814 {
815     int ret = 0;
816 
817 #ifdef NAN_2_0
818     if (length <= 8 || pInValue == NULL) {
819         ALOGE("%s: Invalid Arg TLV Len %d < 4",
820               __func__, length);
821         return -1;
822     }
823 
824     pRxDisc->type = (NanConnectionType) pInValue[0];
825     pRxDisc->role = (NanDeviceRole) pInValue[1];
826     pRxDisc->duration = (NanAvailDuration) (pInValue[2] & 0x03);
827     pRxDisc->mapid = ((pInValue[2] >> 2) & 0x0F);
828     memcpy(&pRxDisc->avail_interval_bitmap,
829            &pInValue[4],
830            sizeof(pRxDisc->avail_interval_bitmap));
831 
832     u8 *pInputTlv = (u8 *)&pInValue[8];
833     NanTlv outputTlv;
834     u16 readLen = 0;
835     int remainingLen = (length - 8);
836 
837     //Has Mac address
838     if (remainingLen <= 0) {
839         ALOGE("%s: No TLV's present",__func__);
840         return -1;
841     }
842 
843     ALOGI("%s: TLV remaining Len:%d",__func__, remainingLen);
844     while ((remainingLen > 0) &&
845            (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
846         ALOGI("%s: Remaining Len:%d readLen:%d type:%d length:%d",
847               __func__, remainingLen, readLen, outputTlv.type,
848               outputTlv.length);
849         switch (outputTlv.type) {
850         case NAN_TLV_TYPE_MAC_ADDRESS:
851             if (outputTlv.length > sizeof(pRxDisc->addr)) {
852                 outputTlv.length = sizeof(pRxDisc->addr);
853             }
854             memcpy(pRxDisc->addr, outputTlv.value, outputTlv.length);
855             break;
856         case NAN_TLV_TYPE_WLAN_MESH_ID:
857             if (outputTlv.length > sizeof(pRxDisc->mesh_id)) {
858                 outputTlv.length = sizeof(pRxDisc->mesh_id);
859             }
860             memcpy(pRxDisc->mesh_id, outputTlv.value, outputTlv.length);
861             pRxDisc->mesh_id_len = outputTlv.length;
862             break;
863         case NAN_TLV_TYPE_WLAN_INFRASTRUCTURE_SSID:
864             if (outputTlv.length > sizeof(pRxDisc->infrastructure_ssid_val)) {
865                 outputTlv.length = sizeof(pRxDisc->infrastructure_ssid_val);
866             }
867             memcpy(pRxDisc->infrastructure_ssid_val, outputTlv.value,
868                    outputTlv.length);
869             pRxDisc->infrastructure_ssid_len = outputTlv.length;
870         default:
871             ALOGI("Unhandled TLV Type:%d", outputTlv.type);
872             break;
873         }
874         remainingLen -= readLen;
875         pInputTlv += readLen;
876         memset(&outputTlv,0, sizeof(outputTlv));
877     }
878 #endif /* NAN_2_0 */
879     return ret;
880 }
881 
getNanFurtherAvailabilityMap(const u8 * pInValue,u32 length,NanFurtherAvailabilityMap * pFam)882 int NanCommand::getNanFurtherAvailabilityMap(const u8 *pInValue,
883                                              u32 length,
884                                              NanFurtherAvailabilityMap *pFam)
885 {
886 #ifdef NAN_2_0
887     int idx = 0;
888 
889     if ((length == 0) || pInValue == NULL) {
890         ALOGE("%s: Invalid Arg TLV Len %d or pInValue NULL",
891               __func__, length);
892         return -1;
893     }
894 
895     pFam->numchans = pInValue[0];
896     if (pFam->numchans > NAN_MAX_FAM_CHANNELS) {
897         ALOGE("%s: Unable to accommodate numchans %d",
898               __func__, pFam->numchans);
899         return -1;
900     }
901 
902     if (length < (sizeof(u8) +
903         (pFam->numchans * sizeof(NanFurtherAvailabilityChan)))) {
904         ALOGE("%s: Invalid TLV Length", __func__);
905         return -1;
906     }
907 
908     for (idx = 0; idx < pFam->numchans; idx++) {
909         pNanFurtherAvailabilityChan pRsp = \
910               (pNanFurtherAvailabilityChan)((u8 *)&pInValue[1] + \
911               (idx * sizeof(NanFurtherAvailabilityChan)));
912         NanFurtherAvailabilityChannel *pFamChan = &pFam->famchan[idx];
913 
914         pFamChan->entry_control = \
915             (NanAvailDuration)(pRsp->entryCtrl.availIntDuration);
916         pFamChan->mapid = pRsp->entryCtrl.mapId;
917         pFamChan->class_val = pRsp->opClass;
918         pFamChan->channel = pRsp->channel;
919         memcpy(&pFamChan->avail_interval_bitmap,
920                &pRsp->availIntBitmap,
921                sizeof(pFamChan->avail_interval_bitmap));
922     }
923 #endif /* NAN_2_0*/
924     return 0;
925 }
926 
getNanStaParameter(NanStaParameter * pRsp)927 int NanCommand::getNanStaParameter(NanStaParameter *pRsp)
928 {
929     int ret = WIFI_ERROR_NONE;
930     int res = -1;
931 
932     /*
933        Construct NL message to get the sync stats parameter
934        which has all the parameter required by staparameter.
935     */
936     NanStatsRequest syncStats;
937     memset(&syncStats, 0, sizeof(syncStats));
938     syncStats.header.handle = 0x0;
939     syncStats.header.transaction_id = 0x1234;
940     syncStats.stats_id = NAN_STATS_ID_DE_TIMING_SYNC;
941     syncStats.clear = 0;
942 
943     mStaParam = pRsp;
944     ret = putNanStats(&syncStats);
945     if (ret != 0) {
946         ALOGE("%s: putNanStats Error:%d",__func__, ret);
947         goto cleanup;
948     }
949     ret = requestEvent();
950     if (ret != 0) {
951         ALOGE("%s: requestEvent Error:%d",__func__, ret);
952         goto cleanup;
953     }
954 
955     struct timespec abstime;
956     abstime.tv_sec = 4;
957     abstime.tv_nsec = 0;
958     res = mCondition.wait(abstime);
959     if (res == ETIMEDOUT)
960     {
961         ALOGE("%s: Time out happened.", __func__);
962         ret = WIFI_ERROR_TIMED_OUT;
963         goto cleanup;
964     }
965     ALOGI("%s: NanStaparameter Master_pref:%x," \
966           " Random_factor:%x, hop_count:%x " \
967           " beacon_transmit_time:%d", __func__,
968           pRsp->master_pref, pRsp->random_factor,
969           pRsp->hop_count, pRsp->beacon_transmit_time);
970 cleanup:
971     mStaParam = NULL;
972     return (int)ret;
973 }
974