我们通过代码分析wificond的getScanResults流程,在WifiScanningService的getScanResults流程分析中我们分析了HAL层以上的流程,下面我们继续分析HAL层的流程,首先是ScannerImpl的getScanResults方法:
//system/connectivity/wificond/scanning/scanner_impl.h
class ScannerImpl : public android::net::wifi::nl80211::BnWifiScannerImpl {
private:
ScanUtils* const scan_utils_;
}
//system/connectivity/wificond/scanning/scanner_impl.cpp
Status ScannerImpl::getScanResults(vector<NativeScanResult>* out_scan_results) {
if (!CheckIsValid()) {
return Status::ok();
}
if (!scan_utils_->GetScanResult(interface_index_, out_scan_results)) { //调用ScanUtils的GetScanResult方法
LOG(ERROR) << "Failed to get scan results via NL80211";
}
return Status::ok();
}
调用ScanUtils的GetScanResult方法:
//system/connectivity/wificond/scan_utils.cpp
bool ScanUtils::GetScanResult(uint32_t interface_index,
vector<NativeScanResult>* out_scan_results) {
//构造一个NL80211Packet,命名为get_scan,封装nl80211消息为NL80211_CMD_GET_SCAN
NL80211Packet get_scan(
netlink_manager_->GetFamilyId(),
NL80211_CMD_GET_SCAN,
netlink_manager_->GetSequenceNumber(),
getpid());
//添加NLM_F_DUMP标志位,即返回所有满足条件的结果(NLM_F_DUMP = NLM_F_ROOT|NLM_F_MATCH)
get_scan.AddFlag(NLM_F_DUMP);
//构建名为ifindex的NL80211Attr类型对象,key为NL80211_ATTR_IFINDEX,value为interface_index
NL80211Attr<uint32_t> ifindex(NL80211_ATTR_IFINDEX, interface_index);
//将ifindex封装进get_scan
get_scan.AddAttribute(ifindex);
vector<unique_ptr<const NL80211Packet>> response;
if (!netlink_manager_->SendMessageAndGetResponses(get_scan, &response)) { //发送消息
LOG(ERROR) << "NL80211_CMD_GET_SCAN dump failed";
return false;
}
if (response.empty()) {
LOG(INFO) << "Unexpected empty scan result!";
return true;
}
//读取返回结果
for (auto& packet : response) {
if (packet->GetMessageType() == NLMSG_ERROR) {
LOG(ERROR) << "Receive ERROR message: "
<< strerror(packet->GetErrorCode());
continue;
}
//获取返回数据中key为NL80211_ATTR_IFINDEX的值,如果不存在,则跳过
if (packet->GetMessageType() != netlink_manager_->GetFamilyId()) {
LOG(ERROR) << "Wrong message type: "
<< packet->GetMessageType();
continue;
}
uint32_t if_index;
//如果与请求时的值不同,则忽略掉
if (!packet->GetAttributeValue(NL80211_ATTR_IFINDEX, &if_index)) {
LOG(ERROR) << "No interface index in scan result.";
continue;
}
if (if_index != interface_index) {
LOG(WARNING) << "Uninteresting scan result for interface: " << if_index;
continue;
}
NativeScanResult scan_result;
//封装函数ParseScanResult用于解析packet中的数据,并将其封装为scan_result
if (!ParseScanResult(std::move(packet), &scan_result)) {
LOG(DEBUG) << "Ignore invalid scan result";
continue;
}
//将封装好的scan_result存入out_scan_results中,用于最终返回
out_scan_results->push_back(std::move(scan_result));
}
return true;
}
发送消息部分,与请求开始扫描的调用差不多,都会走到NetlinkManager::SendMessageAndGetResponses()中去,后者负责通过继续调用,最终发送nl80211消息到内核,这里就不赘述了;