Home | History | Annotate | Download | only in wifi_hal
      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 "wifi_hal.h"
     21 #include "nan_i.h"
     22 #include "nancommand.h"
     23 #include <errno.h>
     24 
     25 //Function which calls the necessaryIndication callback
     26 //based on the indication type
     27 int NanCommand::handleNanIndication()
     28 {
     29     //Based on the message_id in the header determine the Indication type
     30     //and call the necessary callback handler
     31     u16 msg_id;
     32     int res = 0;
     33 
     34     msg_id = getIndicationType();
     35 
     36     ALOGV("handleNanIndication msg_id:%u", msg_id);
     37     switch (msg_id) {
     38     case NAN_INDICATION_PUBLISH_REPLIED:
     39         NanPublishRepliedInd publishRepliedInd;
     40         memset(&publishRepliedInd, 0, sizeof(publishRepliedInd));
     41         res = getNanPublishReplied(&publishRepliedInd);
     42         if (!res && mHandler.EventPublishReplied) {
     43             (*mHandler.EventPublishReplied)(&publishRepliedInd);
     44         }
     45         break;
     46 
     47     case NAN_INDICATION_PUBLISH_TERMINATED:
     48         NanPublishTerminatedInd publishTerminatedInd;
     49         memset(&publishTerminatedInd, 0, sizeof(publishTerminatedInd));
     50         res = getNanPublishTerminated(&publishTerminatedInd);
     51         if (!res && mHandler.EventPublishTerminated) {
     52             (*mHandler.EventPublishTerminated)(&publishTerminatedInd);
     53         }
     54         break;
     55 
     56     case NAN_INDICATION_MATCH:
     57         NanMatchInd matchInd;
     58         memset(&matchInd, 0, sizeof(matchInd));
     59         res = getNanMatch(&matchInd);
     60         if (!res && mHandler.EventMatch) {
     61             (*mHandler.EventMatch)(&matchInd);
     62         }
     63         break;
     64 
     65     case NAN_INDICATION_MATCH_EXPIRED:
     66         NanMatchExpiredInd matchExpiredInd;
     67         memset(&matchExpiredInd, 0, sizeof(matchExpiredInd));
     68         res = getNanMatchExpired(&matchExpiredInd);
     69         if (!res && mHandler.EventMatchExpired) {
     70             (*mHandler.EventMatchExpired)(&matchExpiredInd);
     71         }
     72         break;
     73 
     74     case NAN_INDICATION_SUBSCRIBE_TERMINATED:
     75         NanSubscribeTerminatedInd subscribeTerminatedInd;
     76         memset(&subscribeTerminatedInd, 0, sizeof(subscribeTerminatedInd));
     77         res = getNanSubscribeTerminated(&subscribeTerminatedInd);
     78         if (!res && mHandler.EventSubscribeTerminated) {
     79             (*mHandler.EventSubscribeTerminated)(&subscribeTerminatedInd);
     80         }
     81         break;
     82 
     83     case NAN_INDICATION_DE_EVENT:
     84         NanDiscEngEventInd discEngEventInd;
     85         memset(&discEngEventInd, 0, sizeof(discEngEventInd));
     86         res = getNanDiscEngEvent(&discEngEventInd);
     87         if (!res && mHandler.EventDiscEngEvent) {
     88             (*mHandler.EventDiscEngEvent)(&discEngEventInd);
     89         }
     90         break;
     91 
     92     case NAN_INDICATION_FOLLOWUP:
     93         NanFollowupInd followupInd;
     94         memset(&followupInd, 0, sizeof(followupInd));
     95         res = getNanFollowup(&followupInd);
     96         if (!res && mHandler.EventFollowup) {
     97             (*mHandler.EventFollowup)(&followupInd);
     98         }
     99         break;
    100 
    101     case NAN_INDICATION_DISABLED:
    102         NanDisabledInd disabledInd;
    103         memset(&disabledInd, 0, sizeof(disabledInd));
    104         res = getNanDisabled(&disabledInd);
    105         if (!res && mHandler.EventDisabled) {
    106             (*mHandler.EventDisabled)(&disabledInd);
    107         }
    108         break;
    109 
    110     case NAN_INDICATION_TCA:
    111         NanTCAInd tcaInd;
    112         memset(&tcaInd, 0, sizeof(tcaInd));
    113         res = getNanTca(&tcaInd);
    114         if (!res && mHandler.EventTca) {
    115             (*mHandler.EventTca)(&tcaInd);
    116         }
    117         break;
    118 
    119     case NAN_INDICATION_BEACON_SDF_PAYLOAD:
    120         NanBeaconSdfPayloadInd beaconSdfPayloadInd;
    121         memset(&beaconSdfPayloadInd, 0, sizeof(beaconSdfPayloadInd));
    122         res = getNanBeaconSdfPayload(&beaconSdfPayloadInd);
    123         if (!res && mHandler.EventBeaconSdfPayload) {
    124             (*mHandler.EventBeaconSdfPayload)(&beaconSdfPayloadInd);
    125         }
    126         break;
    127 
    128     case NAN_INDICATION_SELF_TRANSMIT_FOLLOWUP:
    129         NanTransmitFollowupInd transmitFollowupInd;
    130         memset(&transmitFollowupInd, 0, sizeof(NanTransmitFollowupInd));
    131         res = getNanTransmitFollowupInd(&transmitFollowupInd);
    132         if (!res && mHandler.EventTransmitFollowup) {
    133             (*mHandler.EventTransmitFollowup)(&transmitFollowupInd);
    134         }
    135         break;
    136 
    137     case NAN_INDICATION_RANGING_REQUEST_RECEIVED:
    138         NanRangeRequestInd rangeRequestInd;
    139         memset(&rangeRequestInd, 0, sizeof(NanRangeRequestInd));
    140         res = getNanRangeRequestReceivedInd(&rangeRequestInd);
    141         if (!res && mHandler.EventRangeRequest) {
    142             (*mHandler.EventRangeRequest)(&rangeRequestInd);
    143         }
    144         break;
    145 
    146     case NAN_INDICATION_RANGING_RESULT:
    147         NanRangeReportInd rangeReportInd;
    148         memset(&rangeReportInd, 0, sizeof(NanRangeReportInd));
    149         res = getNanRangeReportInd(&rangeReportInd);
    150         if (!res && mHandler.EventRangeReport) {
    151             (*mHandler.EventRangeReport)(&rangeReportInd);
    152         }
    153         break;
    154 
    155     default:
    156         ALOGE("handleNanIndication error invalid msg_id:%u", msg_id);
    157         res = (int)WIFI_ERROR_INVALID_REQUEST_ID;
    158         break;
    159     }
    160     return res;
    161 }
    162 
    163 //Function which will return the Nan Indication type based on
    164 //the initial few bytes of mNanVendorEvent
    165 NanIndicationType NanCommand::getIndicationType()
    166 {
    167     if (mNanVendorEvent == NULL) {
    168         ALOGE("%s: Invalid argument mNanVendorEvent:%p",
    169               __func__, mNanVendorEvent);
    170         return NAN_INDICATION_UNKNOWN;
    171     }
    172 
    173     NanMsgHeader *pHeader = (NanMsgHeader *)mNanVendorEvent;
    174 
    175     switch (pHeader->msgId) {
    176     case NAN_MSG_ID_PUBLISH_REPLIED_IND:
    177         return NAN_INDICATION_PUBLISH_REPLIED;
    178     case NAN_MSG_ID_PUBLISH_TERMINATED_IND:
    179         return NAN_INDICATION_PUBLISH_TERMINATED;
    180     case NAN_MSG_ID_MATCH_IND:
    181         return NAN_INDICATION_MATCH;
    182     case NAN_MSG_ID_MATCH_EXPIRED_IND:
    183         return NAN_INDICATION_MATCH_EXPIRED;
    184     case NAN_MSG_ID_FOLLOWUP_IND:
    185         return NAN_INDICATION_FOLLOWUP;
    186     case NAN_MSG_ID_SUBSCRIBE_TERMINATED_IND:
    187         return NAN_INDICATION_SUBSCRIBE_TERMINATED;
    188     case  NAN_MSG_ID_DE_EVENT_IND:
    189         return NAN_INDICATION_DE_EVENT;
    190     case NAN_MSG_ID_DISABLE_IND:
    191         return NAN_INDICATION_DISABLED;
    192     case NAN_MSG_ID_TCA_IND:
    193         return NAN_INDICATION_TCA;
    194     case NAN_MSG_ID_BEACON_SDF_IND:
    195         return NAN_INDICATION_BEACON_SDF_PAYLOAD;
    196     case NAN_MSG_ID_SELF_TRANSMIT_FOLLOWUP_IND:
    197         return NAN_INDICATION_SELF_TRANSMIT_FOLLOWUP;
    198     case NAN_MSG_ID_RANGING_REQUEST_RECEVD_IND:
    199         return NAN_INDICATION_RANGING_REQUEST_RECEIVED;
    200     case NAN_MSG_ID_RANGING_RESULT_IND:
    201         return NAN_INDICATION_RANGING_RESULT;
    202     default:
    203         return NAN_INDICATION_UNKNOWN;
    204     }
    205 }
    206 
    207 int NanCommand::getNanPublishReplied(NanPublishRepliedInd *event)
    208 {
    209     if (event == NULL || mNanVendorEvent == NULL) {
    210         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
    211               __func__, event, mNanVendorEvent);
    212         return WIFI_ERROR_INVALID_ARGS;
    213     }
    214 
    215     pNanPublishRepliedIndMsg pRsp = (pNanPublishRepliedIndMsg)mNanVendorEvent;
    216     event->requestor_instance_id = pRsp->publishRepliedIndParams.matchHandle;
    217 
    218     event->rssi_value = 0;
    219     u8 *pInputTlv = pRsp->ptlv;
    220     NanTlv outputTlv;
    221     u16 readLen = 0;
    222     int remainingLen = (mNanDataLen - \
    223         (sizeof(NanMsgHeader)));
    224 
    225     if (remainingLen <= 0) {
    226         ALOGI("%s: No TLV's present",__func__);
    227         return WIFI_SUCCESS;
    228     }
    229     while ((remainingLen > 0) &&
    230            (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
    231         switch (outputTlv.type) {
    232         case NAN_TLV_TYPE_MAC_ADDRESS:
    233             if (outputTlv.length > sizeof(event->addr)) {
    234                 outputTlv.length = sizeof(event->addr);
    235             }
    236             memcpy(event->addr, outputTlv.value, outputTlv.length);
    237             break;
    238         case NAN_TLV_TYPE_RECEIVED_RSSI_VALUE:
    239             if (outputTlv.length > sizeof(event->rssi_value)) {
    240                 outputTlv.length = sizeof(event->rssi_value);
    241             }
    242             memcpy(&event->rssi_value, outputTlv.value,
    243                    outputTlv.length);
    244             break;
    245         default:
    246             ALOGI("Unknown TLV type skipped");
    247             break;
    248         }
    249         remainingLen -= readLen;
    250         pInputTlv += readLen;
    251         memset(&outputTlv, 0, sizeof(outputTlv));
    252     }
    253     return WIFI_SUCCESS;
    254 }
    255 
    256 int NanCommand::getNanPublishTerminated(NanPublishTerminatedInd *event)
    257 {
    258     if (event == NULL || mNanVendorEvent == NULL) {
    259         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
    260               __func__, event, mNanVendorEvent);
    261         return WIFI_ERROR_INVALID_ARGS;
    262     }
    263 
    264     pNanPublishTerminatedIndMsg pRsp = (pNanPublishTerminatedIndMsg)mNanVendorEvent;
    265     event->publish_id = pRsp->fwHeader.handle;
    266     NanErrorTranslation((NanInternalStatusType)pRsp->reason, 0,
    267                         (void*)event, false);
    268     return WIFI_SUCCESS;
    269 }
    270 
    271 int NanCommand::getNanMatch(NanMatchInd *event)
    272 {
    273     if (event == NULL || mNanVendorEvent == NULL) {
    274         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
    275               __func__, event, mNanVendorEvent);
    276         return WIFI_ERROR_INVALID_ARGS;
    277     }
    278 
    279     pNanMatchIndMsg pRsp = (pNanMatchIndMsg)mNanVendorEvent;
    280     event->publish_subscribe_id = pRsp->fwHeader.handle;
    281     event->requestor_instance_id = pRsp->matchIndParams.matchHandle;
    282     event->match_occured_flag = pRsp->matchIndParams.matchOccuredFlag;
    283     event->out_of_resource_flag = pRsp->matchIndParams.outOfResourceFlag;
    284 
    285     u8 *pInputTlv = pRsp->ptlv;
    286     NanTlv outputTlv;
    287     u16 readLen = 0;
    288     int remainingLen = (mNanDataLen - \
    289         (sizeof(NanMsgHeader) + sizeof(NanMatchIndParams)));
    290     int ret = 0, idx = 0;
    291 
    292     //Has SDF match filter and service specific info TLV
    293     if (remainingLen <= 0) {
    294         ALOGV("%s: No TLV's present",__func__);
    295         return WIFI_SUCCESS;
    296     }
    297     ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
    298     while ((remainingLen > 0) &&
    299            (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
    300         ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
    301               __func__, remainingLen, readLen, outputTlv.type,
    302               outputTlv.length);
    303         switch (outputTlv.type) {
    304         case NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO:
    305             if (outputTlv.length > NAN_MAX_SERVICE_NAME_LEN) {
    306                 outputTlv.length = NAN_MAX_SERVICE_NAME_LEN;
    307             }
    308             event->service_specific_info_len = outputTlv.length;
    309             memcpy(event->service_specific_info, outputTlv.value,
    310                    outputTlv.length);
    311             break;
    312         case NAN_TLV_TYPE_SDF_MATCH_FILTER:
    313             if (outputTlv.length > NAN_MAX_MATCH_FILTER_LEN) {
    314                 outputTlv.length = NAN_MAX_MATCH_FILTER_LEN;
    315             }
    316             event->sdf_match_filter_len = outputTlv.length;
    317             memcpy(event->sdf_match_filter, outputTlv.value,
    318                    outputTlv.length);
    319             break;
    320         case NAN_TLV_TYPE_MAC_ADDRESS:
    321             if (outputTlv.length > sizeof(event->addr)) {
    322                 outputTlv.length = sizeof(event->addr);
    323             }
    324             memcpy(event->addr, outputTlv.value, outputTlv.length);
    325             break;
    326         case NAN_TLV_TYPE_RECEIVED_RSSI_VALUE:
    327             if (outputTlv.length > sizeof(event->rssi_value)) {
    328                 outputTlv.length = sizeof(event->rssi_value);
    329             }
    330             memcpy(&event->rssi_value, outputTlv.value,
    331                    outputTlv.length);
    332             break;
    333         case NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE:
    334             if (outputTlv.length != sizeof(u32)) {
    335                 ALOGE("NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE"
    336                       "Incorrect size:%d expecting %zu", outputTlv.length,
    337                       sizeof(u32));
    338                 break;
    339             }
    340             event->is_conn_capability_valid = 1;
    341             /* Populate conn_capability from received TLV */
    342             getNanReceivePostConnectivityCapabilityVal(outputTlv.value,
    343                                                        &event->conn_capability);
    344             break;
    345         case NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE:
    346             /* Populate receive discovery attribute from
    347                received TLV */
    348             idx = event->num_rx_discovery_attr;
    349             ret = getNanReceivePostDiscoveryVal(outputTlv.value,
    350                                                 outputTlv.length,
    351                                                 &event->discovery_attr[idx]);
    352             if (ret == 0) {
    353                 event->num_rx_discovery_attr++;
    354             } else {
    355                 ALOGE("NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE"
    356                       "Incorrect");
    357             }
    358             break;
    359         case NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP:
    360             /* Populate further availability bitmap from
    361                received TLV */
    362             ret = getNanFurtherAvailabilityMap(outputTlv.value,
    363                                                outputTlv.length,
    364                                                &event->num_chans,
    365                                                &event->famchan[0]);
    366             if (ret < 0)
    367                 ALOGE("NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP"
    368                       "Incorrect");
    369             break;
    370         case NAN_TLV_TYPE_CLUSTER_ATTRIBUTE:
    371             if (outputTlv.length > sizeof(event->cluster_attribute)) {
    372                 outputTlv.length = sizeof(event->cluster_attribute);
    373             }
    374             memcpy(event->cluster_attribute,
    375                    outputTlv.value, outputTlv.length);
    376             event->cluster_attribute_len = outputTlv.length;
    377             break;
    378         case NAN_TLV_TYPE_NAN_CSID:
    379             if (outputTlv.length > sizeof(event->peer_cipher_type)) {
    380                 outputTlv.length = sizeof(event->peer_cipher_type);
    381             }
    382             memcpy(&event->peer_cipher_type, outputTlv.value,
    383                    outputTlv.length);
    384             break;
    385         case NAN_TLV_TYPE_NAN_SCID:
    386             if (outputTlv.length > sizeof(event->scid)) {
    387                 outputTlv.length = sizeof(event->scid);
    388             }
    389             event->scid_len = outputTlv.length;
    390             memcpy(event->scid, outputTlv.value, outputTlv.length);
    391             break;
    392         case NAN_TLV_TYPE_SDEA_CTRL_PARAMS:
    393             if (outputTlv.length != sizeof(u32)) {
    394                 ALOGE("NAN_TLV_TYPE_SDEA_CTRL_PARAMS"
    395                       "Incorrect size:%d expecting %zu", outputTlv.length,
    396                       sizeof(u32));
    397                 break;
    398             }
    399             getNanReceiveSdeaCtrlParams(outputTlv.value,
    400                                              &event->peer_sdea_params);
    401             break;
    402         case NAN_TLV_TYPE_NAN20_RANGING_RESULT:
    403             if (outputTlv.length > sizeof(event->range_info)) {
    404                 outputTlv.length = sizeof(event->range_info);
    405             }
    406             memcpy(&event->range_info, outputTlv.value, outputTlv.length);
    407             break;
    408         case NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO:
    409             if (outputTlv.length > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
    410                 outputTlv.length = NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN;
    411             }
    412             event->sdea_service_specific_info_len = outputTlv.length;
    413             memcpy(event->sdea_service_specific_info, outputTlv.value,
    414                    outputTlv.length);
    415             break;
    416         default:
    417             ALOGV("Unknown TLV type skipped");
    418             break;
    419         }
    420         remainingLen -= readLen;
    421         pInputTlv += readLen;
    422         memset(&outputTlv, 0, sizeof(outputTlv));
    423     }
    424     return WIFI_SUCCESS;
    425 }
    426 
    427 int NanCommand::getNanMatchExpired(NanMatchExpiredInd *event)
    428 {
    429     if (event == NULL || mNanVendorEvent == NULL) {
    430         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
    431               __func__, event, mNanVendorEvent);
    432         return WIFI_ERROR_INVALID_ARGS;
    433     }
    434 
    435     pNanMatchExpiredIndMsg pRsp = (pNanMatchExpiredIndMsg)mNanVendorEvent;
    436     event->publish_subscribe_id = pRsp->fwHeader.handle;
    437     event->requestor_instance_id = pRsp->matchExpiredIndParams.matchHandle;
    438     return WIFI_SUCCESS;
    439 }
    440 
    441 int NanCommand::getNanSubscribeTerminated(NanSubscribeTerminatedInd *event)
    442 {
    443     if (event == NULL || mNanVendorEvent == NULL) {
    444         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
    445               __func__, event, mNanVendorEvent);
    446         return WIFI_ERROR_INVALID_ARGS;
    447     }
    448 
    449     pNanSubscribeTerminatedIndMsg pRsp = (pNanSubscribeTerminatedIndMsg)mNanVendorEvent;
    450     event->subscribe_id = pRsp->fwHeader.handle;
    451     NanErrorTranslation((NanInternalStatusType)pRsp->reason, 0,
    452                         (void*)event, false);
    453     return WIFI_SUCCESS;
    454 }
    455 
    456 int NanCommand::getNanFollowup(NanFollowupInd *event)
    457 {
    458     if (event == NULL || mNanVendorEvent == NULL) {
    459         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
    460               __func__, event, mNanVendorEvent);
    461         return WIFI_ERROR_INVALID_ARGS;
    462     }
    463 
    464     pNanFollowupIndMsg pRsp = (pNanFollowupIndMsg)mNanVendorEvent;
    465     event->publish_subscribe_id = pRsp->fwHeader.handle;
    466     event->requestor_instance_id = pRsp->followupIndParams.matchHandle;
    467     event->dw_or_faw = pRsp->followupIndParams.window;
    468 
    469     u8 *pInputTlv = pRsp->ptlv;
    470     NanTlv outputTlv;
    471     u16 readLen = 0;
    472     int remainingLen = (mNanDataLen -  \
    473         (sizeof(NanMsgHeader) + sizeof(NanFollowupIndParams)));
    474 
    475     //Has service specific info and extended service specific info TLV
    476     if (remainingLen <= 0) {
    477         ALOGV("%s: No TLV's present",__func__);
    478         return WIFI_SUCCESS;
    479     }
    480     ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
    481     while ((remainingLen > 0) &&
    482            (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
    483         ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
    484               __func__, remainingLen, readLen, outputTlv.type,
    485               outputTlv.length);
    486         switch (outputTlv.type) {
    487         case NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO:
    488         case NAN_TLV_TYPE_EXT_SERVICE_SPECIFIC_INFO:
    489             if (outputTlv.length > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
    490                 outputTlv.length = NAN_MAX_SERVICE_SPECIFIC_INFO_LEN;
    491             }
    492             event->service_specific_info_len = outputTlv.length;
    493             memcpy(event->service_specific_info, outputTlv.value,
    494                    outputTlv.length);
    495             break;
    496         case NAN_TLV_TYPE_MAC_ADDRESS:
    497             if (outputTlv.length > sizeof(event->addr)) {
    498                 outputTlv.length = sizeof(event->addr);
    499             }
    500             memcpy(event->addr, outputTlv.value, outputTlv.length);
    501             break;
    502         case NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO:
    503             if (outputTlv.length > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
    504                 outputTlv.length = NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN;
    505             }
    506             event->sdea_service_specific_info_len = outputTlv.length;
    507             memcpy(event->sdea_service_specific_info, outputTlv.value,
    508                    outputTlv.length);
    509             break;
    510         default:
    511             ALOGV("Unknown TLV type skipped");
    512             break;
    513         }
    514         remainingLen -= readLen;
    515         pInputTlv += readLen;
    516         memset(&outputTlv, 0, sizeof(outputTlv));
    517     }
    518     return WIFI_SUCCESS;
    519 }
    520 
    521 int NanCommand::getNanDiscEngEvent(NanDiscEngEventInd *event)
    522 {
    523     if (event == NULL || mNanVendorEvent == NULL) {
    524         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
    525               __func__, event, mNanVendorEvent);
    526         return WIFI_ERROR_INVALID_ARGS;
    527     }
    528 
    529     pNanEventIndMsg pRsp = (pNanEventIndMsg)mNanVendorEvent;
    530     memset(&event->data, 0, sizeof(event->data));
    531 
    532     u8 *pInputTlv = pRsp->ptlv;
    533     NanTlv outputTlv;
    534     u16 readLen = 0;
    535     int remainingLen = (mNanDataLen -  \
    536         (sizeof(NanMsgHeader)));
    537 
    538     //Has Self-STA Mac TLV
    539     if (remainingLen <= 0) {
    540         ALOGE("%s: No TLV's present",__func__);
    541         return WIFI_SUCCESS;
    542     }
    543 
    544     ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
    545     while ((remainingLen > 0) &&
    546            (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
    547         ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
    548               __func__, remainingLen, readLen, outputTlv.type,
    549               outputTlv.length);
    550         switch (outputTlv.type) {
    551         case NAN_TLV_TYPE_EVENT_SELF_STATION_MAC_ADDRESS:
    552             if (outputTlv.length > NAN_MAC_ADDR_LEN) {
    553                 ALOGV("%s: Reading only first %d bytes of TLV",
    554                       __func__, NAN_MAC_ADDR_LEN);
    555                 outputTlv.length = NAN_MAC_ADDR_LEN;
    556             }
    557             memcpy(event->data.mac_addr.addr, outputTlv.value,
    558                    outputTlv.length);
    559             event->event_type = NAN_EVENT_ID_DISC_MAC_ADDR;
    560             break;
    561         case NAN_TLV_TYPE_EVENT_STARTED_CLUSTER:
    562             if (outputTlv.length > NAN_MAC_ADDR_LEN) {
    563                 ALOGV("%s: Reading only first %d bytes of TLV",
    564                       __func__, NAN_MAC_ADDR_LEN);
    565                 outputTlv.length = NAN_MAC_ADDR_LEN;
    566             }
    567             memcpy(event->data.cluster.addr, outputTlv.value,
    568                    outputTlv.length);
    569             event->event_type = NAN_EVENT_ID_STARTED_CLUSTER;
    570             break;
    571         case NAN_TLV_TYPE_EVENT_JOINED_CLUSTER:
    572             if (outputTlv.length > NAN_MAC_ADDR_LEN) {
    573                 ALOGV("%s: Reading only first %d bytes of TLV",
    574                       __func__, NAN_MAC_ADDR_LEN);
    575                 outputTlv.length = NAN_MAC_ADDR_LEN;
    576             }
    577             memcpy(event->data.cluster.addr, outputTlv.value,
    578                    outputTlv.length);
    579             event->event_type = NAN_EVENT_ID_JOINED_CLUSTER;
    580             break;
    581         default:
    582             ALOGV("Unhandled TLV type:%d", outputTlv.type);
    583             break;
    584         }
    585         remainingLen -= readLen;
    586         pInputTlv += readLen;
    587         memset(&outputTlv,0, sizeof(outputTlv));
    588     }
    589     return WIFI_SUCCESS;
    590 }
    591 
    592 int NanCommand::getNanDisabled(NanDisabledInd *event)
    593 {
    594     if (event == NULL || mNanVendorEvent == NULL) {
    595         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
    596               __func__, event, mNanVendorEvent);
    597         return WIFI_ERROR_INVALID_ARGS;
    598     }
    599 
    600     pNanDisableIndMsg pRsp = (pNanDisableIndMsg)mNanVendorEvent;
    601     NanErrorTranslation((NanInternalStatusType)pRsp->reason, 0,
    602                         (void*)event, false);
    603     return WIFI_SUCCESS;
    604 
    605 }
    606 
    607 int NanCommand::getNanTca(NanTCAInd *event)
    608 {
    609     if (event == NULL || mNanVendorEvent == NULL) {
    610         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
    611               __func__, event, mNanVendorEvent);
    612         return WIFI_ERROR_INVALID_ARGS;
    613     }
    614 
    615     pNanTcaIndMsg pRsp = (pNanTcaIndMsg)mNanVendorEvent;
    616     memset(&event->data, 0, sizeof(event->data));
    617 
    618     u8 *pInputTlv = pRsp->ptlv;
    619     NanTlv outputTlv;
    620     u16 readLen = 0;
    621 
    622     int remainingLen = (mNanDataLen -  \
    623         (sizeof(NanMsgHeader)));
    624 
    625     //Has NAN_TCA_ID_CLUSTER_SIZE
    626     if (remainingLen <= 0) {
    627         ALOGE("%s: No TLV's present",__func__);
    628         return WIFI_SUCCESS;
    629     }
    630 
    631     ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
    632     while ((remainingLen > 0) &&
    633            (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
    634         ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
    635               __func__, remainingLen, readLen, outputTlv.type,
    636               outputTlv.length);
    637         switch (outputTlv.type) {
    638         case NAN_TLV_TYPE_CLUSTER_SIZE_RSP:
    639             if (outputTlv.length != 2 * sizeof(u32)) {
    640                 ALOGE("%s: Wrong length %d in Tca Indication expecting %zu bytes",
    641                       __func__, outputTlv.length, 2 * sizeof(u32));
    642                 break;
    643             }
    644             event->rising_direction_evt_flag = outputTlv.value[0] & 0x01;
    645             event->falling_direction_evt_flag = (outputTlv.value[0] & 0x02) >> 1;
    646             memcpy(&(event->data.cluster.cluster_size), &outputTlv.value[4],
    647                    sizeof(event->data.cluster.cluster_size));
    648             event->tca_type = NAN_TCA_ID_CLUSTER_SIZE;
    649             break;
    650         default:
    651             ALOGV("Unhandled TLV type:%d", outputTlv.type);
    652             break;
    653         }
    654         remainingLen -= readLen;
    655         pInputTlv += readLen;
    656         memset(&outputTlv,0, sizeof(outputTlv));
    657     }
    658     return WIFI_SUCCESS;
    659 }
    660 
    661 int NanCommand::getNanBeaconSdfPayload(NanBeaconSdfPayloadInd *event)
    662 {
    663     if (event == NULL || mNanVendorEvent == NULL) {
    664         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
    665               __func__, event, mNanVendorEvent);
    666         return WIFI_ERROR_INVALID_ARGS;
    667     }
    668 
    669     pNanBeaconSdfPayloadIndMsg pRsp = (pNanBeaconSdfPayloadIndMsg)mNanVendorEvent;
    670     memset(&event->data, 0, sizeof(event->data));
    671 
    672     u8 *pInputTlv = pRsp->ptlv;
    673     NanTlv outputTlv;
    674     u16 readLen = 0;
    675     int remainingLen = (mNanDataLen -  \
    676         (sizeof(NanMsgHeader)));
    677 
    678     //Has Mac address
    679     if (remainingLen <= 0) {
    680         ALOGV("%s: No TLV's present",__func__);
    681         return WIFI_SUCCESS;
    682     }
    683 
    684     ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
    685     while ((remainingLen > 0) &&
    686            (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
    687         ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
    688               __func__, remainingLen, readLen, outputTlv.type,
    689               outputTlv.length);
    690         switch (outputTlv.type) {
    691         case NAN_TLV_TYPE_MAC_ADDRESS:
    692             if (outputTlv.length > sizeof(event->addr)) {
    693                 outputTlv.length = sizeof(event->addr);
    694             }
    695             memcpy(event->addr, outputTlv.value,
    696                    outputTlv.length);
    697             break;
    698 
    699         case NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE:
    700         {
    701             NanReceiveVendorSpecificAttribute* recvVsaattr = &event->vsa;
    702             if (outputTlv.length < sizeof(u32)) {
    703                 ALOGE("NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE"
    704                       "Incorrect length:%d", outputTlv.length);
    705                 break;
    706             }
    707             event->is_vsa_received = 1;
    708             recvVsaattr->vsa_received_on = (outputTlv.value[0] >> 1) & 0x07;
    709             memcpy(&recvVsaattr->vendor_oui, &outputTlv.value[1],
    710                    3);
    711             recvVsaattr->attr_len = outputTlv.length - 4;
    712             if (recvVsaattr->attr_len > NAN_MAX_VSA_DATA_LEN) {
    713                 recvVsaattr->attr_len = NAN_MAX_VSA_DATA_LEN;
    714             }
    715             if (recvVsaattr->attr_len) {
    716                 memcpy(recvVsaattr->vsa, &outputTlv.value[4],
    717                        recvVsaattr->attr_len);
    718             }
    719             break;
    720         }
    721 
    722         case NAN_TLV_TYPE_BEACON_SDF_PAYLOAD_RECEIVE:
    723             event->is_beacon_sdf_payload_received = 1;
    724             event->data.frame_len = outputTlv.length;
    725             if (event->data.frame_len > NAN_MAX_FRAME_DATA_LEN) {
    726                 event->data.frame_len = NAN_MAX_FRAME_DATA_LEN;
    727             }
    728             memcpy(&event->data.frame_data, &outputTlv.value[0],
    729                    event->data.frame_len);
    730             break;
    731 
    732         default:
    733             ALOGV("Unhandled TLV Type:%d", outputTlv.type);
    734             break;
    735         }
    736         remainingLen -= readLen;
    737         pInputTlv += readLen;
    738         memset(&outputTlv,0, sizeof(outputTlv));
    739     }
    740     return WIFI_SUCCESS;
    741 }
    742 
    743 void NanCommand::getNanReceivePostConnectivityCapabilityVal(
    744     const u8 *pInValue,
    745     NanReceivePostConnectivityCapability *pRxCapab)
    746 {
    747     if (pInValue && pRxCapab) {
    748         pRxCapab->is_mesh_supported = (pInValue[0] & (0x01 << 5));
    749         pRxCapab->is_ibss_supported = (pInValue[0] & (0x01 << 4));
    750         pRxCapab->wlan_infra_field = (pInValue[0] & (0x01 << 3));
    751         pRxCapab->is_tdls_supported = (pInValue[0] & (0x01 << 2));
    752         pRxCapab->is_wfds_supported = (pInValue[0] & (0x01 << 1));
    753         pRxCapab->is_wfd_supported = pInValue[0] & 0x01;
    754     }
    755 }
    756 
    757 void NanCommand::getNanReceiveSdeaCtrlParams(const u8* pInValue,
    758     NanSdeaCtrlParams *pPeerSdeaParams)
    759 {
    760     if (pInValue && pPeerSdeaParams) {
    761         pPeerSdeaParams->security_cfg =
    762                           (NanDataPathSecurityCfgStatus)((pInValue[0] & BIT_6) ?
    763                            NAN_DP_CONFIG_SECURITY : NAN_DP_CONFIG_NO_SECURITY);
    764         pPeerSdeaParams->ranging_state =
    765                            (NanRangingState)((pInValue[0] & BIT_7) ?
    766                             NAN_RANGING_ENABLE : NAN_RANGING_DISABLE);
    767 #if 0
    768         pPeerSdeaParams->enable_ranging_limit =
    769                          (NanRangingLimitState)((pInValue[0] & BIT_8) ?
    770                           NAN_RANGING_LIMIT_ENABLE : NAN_RANGING_LIMIT_DISABLE);
    771 #endif
    772     }
    773     return;
    774 }
    775 
    776 int NanCommand::getNanReceivePostDiscoveryVal(const u8 *pInValue,
    777                                               u32 length,
    778                                               NanReceivePostDiscovery *pRxDisc)
    779 {
    780     int ret = 0;
    781 
    782     if (length <= 8 || pInValue == NULL) {
    783         ALOGE("%s: Invalid Arg TLV Len %d < 4",
    784               __func__, length);
    785         return -1;
    786     }
    787 
    788     pRxDisc->type = (NanConnectionType) pInValue[0];
    789     pRxDisc->role = (NanDeviceRole) pInValue[1];
    790     pRxDisc->duration = (NanAvailDuration) (pInValue[2] & 0x03);
    791     pRxDisc->mapid = ((pInValue[2] >> 2) & 0x0F);
    792     memcpy(&pRxDisc->avail_interval_bitmap,
    793            &pInValue[4],
    794            sizeof(pRxDisc->avail_interval_bitmap));
    795 
    796     u8 *pInputTlv = (u8 *)&pInValue[8];
    797     NanTlv outputTlv;
    798     u16 readLen = 0;
    799     int remainingLen = (length - 8);
    800 
    801     //Has Mac address
    802     if (remainingLen <= 0) {
    803         ALOGE("%s: No TLV's present",__func__);
    804         return -1;
    805     }
    806 
    807     ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
    808     while ((remainingLen > 0) &&
    809            (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
    810         ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
    811               __func__, remainingLen, readLen, outputTlv.type,
    812               outputTlv.length);
    813         switch (outputTlv.type) {
    814         case NAN_TLV_TYPE_MAC_ADDRESS:
    815             if (outputTlv.length > sizeof(pRxDisc->addr)) {
    816                 outputTlv.length = sizeof(pRxDisc->addr);
    817             }
    818             memcpy(pRxDisc->addr, outputTlv.value, outputTlv.length);
    819             break;
    820         case NAN_TLV_TYPE_WLAN_MESH_ID:
    821             if (outputTlv.length > sizeof(pRxDisc->mesh_id)) {
    822                 outputTlv.length = sizeof(pRxDisc->mesh_id);
    823             }
    824             memcpy(pRxDisc->mesh_id, outputTlv.value, outputTlv.length);
    825             pRxDisc->mesh_id_len = outputTlv.length;
    826             break;
    827         case NAN_TLV_TYPE_WLAN_INFRA_SSID:
    828             if (outputTlv.length > sizeof(pRxDisc->infrastructure_ssid_val)) {
    829                 outputTlv.length = sizeof(pRxDisc->infrastructure_ssid_val);
    830             }
    831             memcpy(pRxDisc->infrastructure_ssid_val, outputTlv.value,
    832                    outputTlv.length);
    833             pRxDisc->infrastructure_ssid_len = outputTlv.length;
    834         default:
    835             ALOGV("Unhandled TLV Type:%d", outputTlv.type);
    836             break;
    837         }
    838         remainingLen -= readLen;
    839         pInputTlv += readLen;
    840         memset(&outputTlv,0, sizeof(outputTlv));
    841     }
    842     return ret;
    843 }
    844 
    845 int NanCommand::getNanFurtherAvailabilityMap(const u8 *pInValue,
    846                                              u32 length,
    847                                              u8 *num_chans,
    848                                              NanFurtherAvailabilityChannel *pFac)
    849 {
    850     int idx = 0;
    851 
    852     if ((length == 0) || pInValue == NULL) {
    853         ALOGE("%s: Invalid Arg TLV Len %d or pInValue NULL",
    854               __func__, length);
    855         return -1;
    856     }
    857 
    858     *num_chans = pInValue[0];
    859     if (*num_chans > NAN_MAX_FAM_CHANNELS) {
    860         ALOGE("%s: Unable to accommodate numchans %d",
    861               __func__, *num_chans);
    862         return -1;
    863     }
    864 
    865     if (length < (sizeof(u8) +
    866         (*num_chans * sizeof(NanFurtherAvailabilityChan)))) {
    867         ALOGE("%s: Invalid TLV Length", __func__);
    868         return -1;
    869     }
    870 
    871     for (idx = 0; idx < *num_chans; idx++) {
    872         pNanFurtherAvailabilityChan pRsp = \
    873               (pNanFurtherAvailabilityChan)((u8 *)&pInValue[1] + \
    874               (idx * sizeof(NanFurtherAvailabilityChan)));
    875 
    876         pFac->entry_control = \
    877             (NanAvailDuration)(pRsp->entryCtrl.availIntDuration);
    878         pFac->mapid = pRsp->entryCtrl.mapId;
    879         pFac->class_val = pRsp->opClass;
    880         pFac->channel = pRsp->channel;
    881         memcpy(&pFac->avail_interval_bitmap,
    882                &pRsp->availIntBitmap,
    883                sizeof(pFac->avail_interval_bitmap));
    884         pFac++;
    885     }
    886     return 0;
    887 }
    888 
    889 wifi_error NanCommand::getNanStaParameter(wifi_interface_handle iface,
    890                                    NanStaParameter *pRsp)
    891 {
    892     wifi_error ret = WIFI_ERROR_NONE;
    893     transaction_id id = 1;
    894     interface_info *ifaceInfo = getIfaceInfo(iface);
    895 
    896     ret = create();
    897     if (ret != WIFI_SUCCESS)
    898         goto cleanup;
    899 
    900     /* Set the interface Id of the message. */
    901     ret = set_iface_id(ifaceInfo->name);
    902     if (ret != WIFI_SUCCESS)
    903         goto cleanup;
    904 
    905     /*
    906        Construct NL message to get the sync stats parameter
    907        which has all the parameter required by staparameter.
    908     */
    909     NanStatsRequest syncStats;
    910     memset(&syncStats, 0, sizeof(syncStats));
    911     syncStats.stats_type = NAN_STATS_ID_DE_TIMING_SYNC;
    912     syncStats.clear = 0;
    913 
    914     mStaParam = pRsp;
    915     ret = putNanStats(id, &syncStats);
    916     if (ret != WIFI_SUCCESS) {
    917         ALOGE("%s: putNanStats Error:%d",__func__, ret);
    918         goto cleanup;
    919     }
    920     ret = requestEvent();
    921     if (ret != 0) {
    922         ALOGE("%s: requestEvent Error:%d",__func__, ret);
    923         goto cleanup;
    924     }
    925 
    926     struct timespec abstime;
    927     abstime.tv_sec = 4;
    928     abstime.tv_nsec = 0;
    929     ret = mCondition.wait(abstime);
    930     if (ret == WIFI_ERROR_TIMED_OUT)
    931     {
    932         ALOGE("%s: Time out happened.", __func__);
    933         goto cleanup;
    934     }
    935     ALOGV("%s: NanStaparameter Master_pref:%x," \
    936           " Random_factor:%x, hop_count:%x " \
    937           " beacon_transmit_time:%d" \
    938           " ndp_channel_freq:%d", __func__,
    939           pRsp->master_pref, pRsp->random_factor,
    940           pRsp->hop_count, pRsp->beacon_transmit_time, pRsp->ndp_channel_freq);
    941 cleanup:
    942     mStaParam = NULL;
    943     return ret;
    944 }
    945 
    946 int NanCommand::getNanTransmitFollowupInd(NanTransmitFollowupInd *event)
    947 {
    948     if (event == NULL || mNanVendorEvent == NULL) {
    949         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
    950               __func__, event, mNanVendorEvent);
    951         return WIFI_ERROR_INVALID_ARGS;
    952     }
    953 
    954     pNanSelfTransmitFollowupIndMsg pRsp = (pNanSelfTransmitFollowupIndMsg)mNanVendorEvent;
    955     event->id = pRsp->fwHeader.transactionId;
    956     NanErrorTranslation((NanInternalStatusType)pRsp->reason, 0,
    957                         (void*)event, false);
    958     return WIFI_SUCCESS;
    959 }
    960 
    961 //Function which calls the necessaryIndication callback
    962 //based on the indication type
    963 int NanCommand::handleNdpIndication(u32 ndpCmdType, struct nlattr **tb_vendor)
    964 {
    965     //Based on the message_id in the header determine the Indication type
    966     //and call the necessary callback handler
    967     int res = 0;
    968 
    969     ALOGI("handleNdpIndication msg_id:%u", ndpCmdType);
    970     switch (ndpCmdType) {
    971     case QCA_WLAN_VENDOR_ATTR_NDP_DATA_REQUEST_IND:
    972         NanDataPathRequestInd ndpRequestInd;
    973         memset(&ndpRequestInd, 0, sizeof(ndpRequestInd));
    974 
    975         res = getNdpRequest(tb_vendor, &ndpRequestInd);
    976         if (!res && mHandler.EventDataRequest) {
    977             (*mHandler.EventDataRequest)(&ndpRequestInd);
    978         }
    979         break;
    980 
    981     case QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND:
    982         NanDataPathConfirmInd ndpConfirmInd;
    983         memset(&ndpConfirmInd, 0, sizeof(ndpConfirmInd));
    984 
    985         res = getNdpConfirm(tb_vendor, &ndpConfirmInd);
    986         if (!res && mHandler.EventDataConfirm) {
    987             (*mHandler.EventDataConfirm)(&ndpConfirmInd);
    988         }
    989         break;
    990 
    991     case QCA_WLAN_VENDOR_ATTR_NDP_END_IND:
    992     {
    993         NanDataPathEndInd *ndpEndInd = NULL;
    994         u8 num_ndp_ids = 0;
    995 
    996         if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) {
    997             ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__);
    998             return WIFI_ERROR_INVALID_ARGS;
    999         }
   1000 
   1001         num_ndp_ids = (u8)(nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY])/sizeof(u32));
   1002         ALOGD("%s: NDP Num Instance Ids : val %d", __FUNCTION__, num_ndp_ids);
   1003 
   1004         if (num_ndp_ids) {
   1005             ndpEndInd =
   1006                 (NanDataPathEndInd *)malloc(sizeof(NanDataPathEndInd)+ (sizeof(u32) * num_ndp_ids));
   1007             if (!ndpEndInd) {
   1008                 ALOGE("%s: ndp_instance_id malloc Failed", __FUNCTION__);
   1009                 return WIFI_ERROR_OUT_OF_MEMORY;
   1010             }
   1011             ndpEndInd->num_ndp_instances = num_ndp_ids;
   1012             nla_memcpy(ndpEndInd->ndp_instance_id,
   1013                        tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY],
   1014                        sizeof(u32) * ndpEndInd->num_ndp_instances);
   1015         }
   1016         if (mHandler.EventDataEnd) {
   1017             (*mHandler.EventDataEnd)(ndpEndInd);
   1018         }
   1019         free(ndpEndInd);
   1020         break;
   1021     }
   1022 
   1023     case QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_IND:
   1024     {
   1025         NanDataPathScheduleUpdateInd *pNdpScheduleUpdateInd;
   1026         u32 num_channels = 0, num_ndp_ids = 0;
   1027 
   1028         if ((!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) ||
   1029             (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_REASON]) ||
   1030             (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY])) {
   1031             ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__);
   1032             return WIFI_ERROR_INVALID_ARGS;
   1033         }
   1034         if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS]) {
   1035              num_channels = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS]);
   1036              ALOGD("%s: num_channels = %d", __FUNCTION__, num_channels);
   1037              if ((num_channels > NAN_MAX_CHANNEL_INFO_SUPPORTED) &&
   1038                  (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO])) {
   1039                  ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO not found", __FUNCTION__);
   1040                  return WIFI_ERROR_INVALID_ARGS;
   1041             }
   1042         }
   1043         num_ndp_ids = (u8)(nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY])/sizeof(u32));
   1044         ALOGD("%s: NDP Num Instance Ids : val %d", __FUNCTION__, num_ndp_ids);
   1045 
   1046         pNdpScheduleUpdateInd =
   1047             (NanDataPathScheduleUpdateInd *)malloc(sizeof(NanDataPathScheduleUpdateInd)
   1048             + (sizeof(u32) * num_ndp_ids));
   1049         if (!pNdpScheduleUpdateInd) {
   1050             ALOGE("%s: NdpScheduleUpdate malloc Failed", __FUNCTION__);
   1051             return WIFI_ERROR_OUT_OF_MEMORY;
   1052         }
   1053         pNdpScheduleUpdateInd->num_channels = num_channels;
   1054         pNdpScheduleUpdateInd->num_ndp_instances = num_ndp_ids;
   1055 
   1056         res = getNdpScheduleUpdate(tb_vendor, pNdpScheduleUpdateInd);
   1057         if (!res && mHandler.EventScheduleUpdate) {
   1058             (*mHandler.EventScheduleUpdate)(pNdpScheduleUpdateInd);
   1059         }
   1060         free(pNdpScheduleUpdateInd);
   1061         break;
   1062     }
   1063     default:
   1064         ALOGE("handleNdpIndication error invalid ndpCmdType:%u", ndpCmdType);
   1065         res = (int)WIFI_ERROR_INVALID_REQUEST_ID;
   1066         break;
   1067     }
   1068     return res;
   1069 }
   1070 
   1071 int NanCommand::getNdpRequest(struct nlattr **tb_vendor,
   1072                               NanDataPathRequestInd *event)
   1073 {
   1074     u32 len = 0;
   1075 
   1076     if (event == NULL || tb_vendor == NULL) {
   1077         ALOGE("%s: Invalid input argument event:%p tb_vendor:%p",
   1078               __FUNCTION__, event, tb_vendor);
   1079         return WIFI_ERROR_INVALID_ARGS;
   1080     }
   1081     if ((!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]) ||
   1082         (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) ||
   1083         (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID])) {
   1084         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__);
   1085         return WIFI_ERROR_INVALID_ARGS;
   1086     }
   1087 
   1088     event->service_instance_id = nla_get_u16(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]);
   1089     ALOGD("%s: Service Instance id : val %d", __FUNCTION__, event->service_instance_id);
   1090 
   1091     len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]);
   1092     len = ((sizeof(event->peer_disc_mac_addr) <= len) ? sizeof(event->peer_disc_mac_addr) : len);
   1093     memcpy(&event->peer_disc_mac_addr[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]), len);
   1094 
   1095     event->ndp_instance_id = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]);
   1096     ALOGD("%s: Ndp Instance id: %d", __FUNCTION__, event->ndp_instance_id);
   1097     if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
   1098         len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
   1099         len = ((sizeof(event->app_info.ndp_app_info) <= len) ? sizeof(event->app_info.ndp_app_info) : len);
   1100         memcpy(&event->app_info.ndp_app_info[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]), len);
   1101         event->app_info.ndp_app_info_len = len;
   1102     } else {
   1103         ALOGD("%s: NDP App Info not present", __FUNCTION__);
   1104     }
   1105     return WIFI_SUCCESS;
   1106 }
   1107 
   1108 int NanCommand::getNdpConfirm(struct nlattr **tb_vendor,
   1109                               NanDataPathConfirmInd *event)
   1110 {
   1111     u32 len = 0;
   1112     NanInternalStatusType drv_reason_code;
   1113     struct nlattr *chInfo;
   1114     NanChannelInfo *pChInfo;
   1115     int rem;
   1116     u32 i = 0;
   1117 
   1118     if (event == NULL || tb_vendor == NULL) {
   1119         ALOGE("%s: Invalid input argument event:%p tb_vendor:%p",
   1120               __FUNCTION__, event, tb_vendor);
   1121         return WIFI_ERROR_INVALID_ARGS;
   1122     }
   1123     if ((!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]) ||
   1124         (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR]) ||
   1125         (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE])) {
   1126         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__);
   1127         return WIFI_ERROR_INVALID_ARGS;
   1128     }
   1129 
   1130     event->ndp_instance_id = nla_get_u16(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]);
   1131     ALOGD("%s: Service Instance id : val %d", __FUNCTION__, event->ndp_instance_id);
   1132 
   1133     len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR]);
   1134     len = ((sizeof(event->peer_ndi_mac_addr) <= len) ? sizeof(event->peer_ndi_mac_addr) : len);
   1135     memcpy(&event->peer_ndi_mac_addr[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR]), len);
   1136 
   1137     event->rsp_code = (NanDataPathResponseCode)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]);
   1138     ALOGD("%s: Response code %d", __FUNCTION__, event->rsp_code);
   1139 
   1140     if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
   1141         len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
   1142         len = ((sizeof(event->app_info.ndp_app_info) <= len) ? sizeof(event->app_info.ndp_app_info) : len);
   1143         memcpy(&event->app_info.ndp_app_info[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]), len);
   1144         event->app_info.ndp_app_info_len = len;
   1145     } else {
   1146         ALOGD("%s: NDP App Info not present", __FUNCTION__);
   1147     }
   1148     drv_reason_code = (NanInternalStatusType)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE]);
   1149     ALOGD("%s: Drv reason code %d", __FUNCTION__, drv_reason_code);
   1150     switch (drv_reason_code) {
   1151         case NDP_I_MGMT_FRAME_REQUEST_FAILED:
   1152         case NDP_I_MGMT_FRAME_RESPONSE_FAILED:
   1153         case NDP_I_MGMT_FRAME_CONFIRM_FAILED:
   1154         case NDP_I_MGMT_FRAME_SECURITY_INSTALL_FAILED:
   1155             event->reason_code = NAN_STATUS_PROTOCOL_FAILURE;
   1156             break;
   1157         default:
   1158             event->reason_code = (NanStatusType)drv_reason_code;
   1159             break;
   1160     }
   1161     ALOGD("%s: Reason code %d", __FUNCTION__, event->reason_code);
   1162 
   1163     if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS]) {
   1164         event->num_channels =
   1165             nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS]);
   1166         ALOGD("%s: num_channels = %d", __FUNCTION__, event->num_channels);
   1167         if ((event->num_channels > NAN_MAX_CHANNEL_INFO_SUPPORTED) &&
   1168             (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO])) {
   1169             ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO not found", __FUNCTION__);
   1170             return WIFI_ERROR_INVALID_ARGS;
   1171         }
   1172     }
   1173 
   1174     if (event->num_channels != 0) {
   1175         for (chInfo =
   1176             (struct nlattr *) nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO]),
   1177             rem = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO]);
   1178             (i < NAN_MAX_CHANNEL_INFO_SUPPORTED && nla_ok(chInfo, rem));
   1179             chInfo = nla_next(chInfo, &(rem))) {
   1180              struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_NDP_MAX + 1];
   1181 
   1182              pChInfo =
   1183                  (NanChannelInfo *) ((u8 *)event->channel_info + (i++ * (sizeof(NanChannelInfo))));
   1184              nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_NDP_MAX,
   1185                  (struct nlattr *) nla_data(chInfo), nla_len(chInfo), NULL);
   1186 
   1187             if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]) {
   1188                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_CHANNEL not found", __FUNCTION__);
   1189                 return WIFI_ERROR_INVALID_ARGS;
   1190             }
   1191             pChInfo->channel = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]);
   1192             ALOGD("%s: Channel = %d", __FUNCTION__, pChInfo->channel);
   1193 
   1194             if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH]) {
   1195                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH not found", __FUNCTION__);
   1196                 return WIFI_ERROR_INVALID_ARGS;
   1197             }
   1198             pChInfo->bandwidth = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH]);
   1199             ALOGD("%s: Channel BW = %d", __FUNCTION__, pChInfo->bandwidth);
   1200 
   1201             if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_NSS]) {
   1202                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_NSS not found", __FUNCTION__);
   1203                 return WIFI_ERROR_INVALID_ARGS;
   1204             }
   1205             pChInfo->nss = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_NSS]);
   1206             ALOGD("%s: No. Spatial Stream = %d", __FUNCTION__, pChInfo->nss);
   1207         }
   1208     }
   1209     return WIFI_SUCCESS;
   1210 }
   1211 
   1212 int NanCommand::getNdpScheduleUpdate(struct nlattr **tb_vendor,
   1213                                      NanDataPathScheduleUpdateInd *event)
   1214 {
   1215     u32 len = 0;
   1216     struct nlattr *chInfo;
   1217     NanChannelInfo *pChInfo;
   1218     int rem;
   1219     u32 i = 0;
   1220 
   1221     len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]);
   1222     len = ((sizeof(event->peer_mac_addr) <= len) ? sizeof(event->peer_mac_addr) : len);
   1223     memcpy(&event->peer_mac_addr[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]), len);
   1224 
   1225     event->schedule_update_reason_code = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_REASON]);
   1226     ALOGD("%s: Reason code %d", __FUNCTION__, event->schedule_update_reason_code);
   1227 
   1228     if (event->num_channels != 0) {
   1229         for (chInfo =
   1230             (struct nlattr *) nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO]),
   1231             rem = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO]);
   1232             (i < NAN_MAX_CHANNEL_INFO_SUPPORTED && nla_ok(chInfo, rem));
   1233             chInfo = nla_next(chInfo, &(rem))) {
   1234             struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_NDP_MAX + 1];
   1235 
   1236             pChInfo =
   1237                 (NanChannelInfo *) ((u8 *)event->channel_info + (i++ * (sizeof(NanChannelInfo))));
   1238             nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_NDP_MAX,
   1239                 (struct nlattr *) nla_data(chInfo), nla_len(chInfo), NULL);
   1240 
   1241             if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]) {
   1242                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_CHANNEL not found", __FUNCTION__);
   1243                 return WIFI_ERROR_INVALID_ARGS;
   1244             }
   1245             pChInfo->channel = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]);
   1246             ALOGD("%s: Channel = %d", __FUNCTION__, pChInfo->channel);
   1247 
   1248             if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH]) {
   1249                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH not found", __FUNCTION__);
   1250                 return WIFI_ERROR_INVALID_ARGS;
   1251             }
   1252             pChInfo->bandwidth = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH]);
   1253             ALOGD("%s: Channel BW = %d", __FUNCTION__, pChInfo->bandwidth);
   1254 
   1255            if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_NSS]) {
   1256                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_NSS not found", __FUNCTION__);
   1257                 return WIFI_ERROR_INVALID_ARGS;
   1258             }
   1259             pChInfo->nss = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_NSS]);
   1260             ALOGD("%s: No. Spatial Stream = %d", __FUNCTION__, pChInfo->nss);
   1261         }
   1262     }
   1263 
   1264     if (event->num_ndp_instances) {
   1265         nla_memcpy(event->ndp_instance_id,
   1266                    tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY],
   1267                    sizeof(u32) * event->num_ndp_instances);
   1268     }
   1269     return WIFI_SUCCESS;
   1270 }
   1271 
   1272 int NanCommand::getNanRangeRequestReceivedInd(NanRangeRequestInd *event)
   1273 {
   1274     if (event == NULL || mNanVendorEvent == NULL) {
   1275         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
   1276               __func__, event, mNanVendorEvent);
   1277         return WIFI_ERROR_INVALID_ARGS;
   1278     }
   1279 
   1280     pNanFWRangeReqRecvdInd pRsp = (pNanFWRangeReqRecvdInd)mNanVendorEvent;
   1281 
   1282     u8 *pInputTlv = pRsp->ptlv;
   1283     NanTlv outputTlv;
   1284     u16 readLen = 0;
   1285 
   1286     int remainingLen = (mNanDataLen -  \
   1287         (sizeof(NanMsgHeader)));
   1288 
   1289     if (remainingLen <= 0) {
   1290         ALOGE("%s: No TLV's present",__func__);
   1291         return WIFI_SUCCESS;
   1292     }
   1293 
   1294     ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
   1295     while ((remainingLen > 0) &&
   1296            (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
   1297         ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
   1298               __func__, remainingLen, readLen, outputTlv.type,
   1299               outputTlv.length);
   1300         switch (outputTlv.type) {
   1301         case NAN_TLV_TYPE_NAN20_RANGING_REQUEST_RECEIVED:
   1302             NanFWRangeReqRecvdMsg fwRangeReqRecvd;
   1303             if (outputTlv.length > sizeof(fwRangeReqRecvd)) {
   1304                 outputTlv.length = sizeof(fwRangeReqRecvd);
   1305             }
   1306             memcpy(&fwRangeReqRecvd, outputTlv.value, outputTlv.length);
   1307             FW_MAC_ADDR_TO_CHAR_ARRAY(fwRangeReqRecvd.range_mac_addr, event->range_req_intf_addr);
   1308             event->publish_id = fwRangeReqRecvd.range_id;
   1309             break;
   1310         default:
   1311             ALOGV("Unhandled TLV type:%d", outputTlv.type);
   1312             break;
   1313         }
   1314         remainingLen -= readLen;
   1315         pInputTlv += readLen;
   1316         memset(&outputTlv,0, sizeof(outputTlv));
   1317     }
   1318     return WIFI_SUCCESS;
   1319 }
   1320 
   1321 int NanCommand::getNanRangeReportInd(NanRangeReportInd *event)
   1322 {
   1323     if (event == NULL || mNanVendorEvent == NULL) {
   1324         ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
   1325               __func__, event, mNanVendorEvent);
   1326         return WIFI_ERROR_INVALID_ARGS;
   1327     }
   1328 
   1329     pNanFWRangeReportInd pRsp = (pNanFWRangeReportInd)mNanVendorEvent;
   1330 
   1331     u8 *pInputTlv = pRsp->ptlv;
   1332     NanTlv outputTlv;
   1333     u16 readLen = 0;
   1334 
   1335     int remainingLen = (mNanDataLen -  \
   1336         (sizeof(NanMsgHeader)));
   1337 
   1338     if (remainingLen <= 0) {
   1339         ALOGE("%s: No TLV's present",__func__);
   1340         return WIFI_SUCCESS;
   1341     }
   1342 
   1343     ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
   1344     while ((remainingLen > 0) &&
   1345            (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
   1346         ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
   1347               __func__, remainingLen, readLen, outputTlv.type,
   1348               outputTlv.length);
   1349         switch (outputTlv.type) {
   1350         case NAN_TLV_TYPE_MAC_ADDRESS:
   1351             if (outputTlv.length > NAN_MAC_ADDR_LEN) {
   1352                 outputTlv.length = NAN_MAC_ADDR_LEN;
   1353             }
   1354             memcpy(event->range_req_intf_addr, outputTlv.value, outputTlv.length);
   1355             break;
   1356 
   1357         case NAN_TLV_TYPE_NAN20_RANGING_RESULT:
   1358             NanFWRangeReportParams range_params;
   1359             if (outputTlv.length > sizeof(NanFWRangeReportParams)) {
   1360                 outputTlv.length = sizeof(NanFWRangeReportParams);
   1361             }
   1362             memcpy(&range_params, outputTlv.value, outputTlv.length);
   1363             event->range_measurement_mm = range_params.range_measurement;
   1364             event->publish_id = range_params.publish_id;
   1365 //          event->event_type = range_params.event_type;
   1366             break;
   1367         default:
   1368             ALOGV("Unhandled TLV type:%d", outputTlv.type);
   1369             break;
   1370         }
   1371         remainingLen -= readLen;
   1372         pInputTlv += readLen;
   1373         memset(&outputTlv,0, sizeof(outputTlv));
   1374     }
   1375     return WIFI_SUCCESS;
   1376 }
   1377