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