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