$search
00001 /* 00002 * hostapd - Driver operations 00003 * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation. 00008 * 00009 * Alternatively, this software may be distributed under the terms of BSD 00010 * license. 00011 * 00012 * See README and COPYING for more details. 00013 */ 00014 00015 #include "utils/includes.h" 00016 00017 #include "utils/common.h" 00018 #include "drivers/driver.h" 00019 #include "common/ieee802_11_defs.h" 00020 #include "hostapd.h" 00021 #include "ieee802_11.h" 00022 #include "sta_info.h" 00023 #include "ap_config.h" 00024 #include "ap_drv_ops.h" 00025 00026 00027 static int hostapd_sta_flags_to_drv(int flags) 00028 { 00029 int res = 0; 00030 if (flags & WLAN_STA_AUTHORIZED) 00031 res |= WPA_STA_AUTHORIZED; 00032 if (flags & WLAN_STA_WMM) 00033 res |= WPA_STA_WMM; 00034 if (flags & WLAN_STA_SHORT_PREAMBLE) 00035 res |= WPA_STA_SHORT_PREAMBLE; 00036 if (flags & WLAN_STA_MFP) 00037 res |= WPA_STA_MFP; 00038 return res; 00039 } 00040 00041 00042 static int hostapd_set_ap_wps_ie(struct hostapd_data *hapd) 00043 { 00044 struct wpabuf *beacon, *proberesp; 00045 int ret; 00046 00047 if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL) 00048 return 0; 00049 00050 beacon = hapd->wps_beacon_ie; 00051 proberesp = hapd->wps_probe_resp_ie; 00052 00053 ret = hapd->driver->set_ap_wps_ie(hapd->drv_priv, beacon, proberesp); 00054 00055 return ret; 00056 } 00057 00058 00059 static int hostapd_send_mgmt_frame(struct hostapd_data *hapd, const void *msg, 00060 size_t len) 00061 { 00062 if (hapd->driver == NULL || hapd->driver->send_mlme == NULL) 00063 return 0; 00064 return hapd->driver->send_mlme(hapd->drv_priv, msg, len); 00065 } 00066 00067 00068 static int hostapd_send_eapol(struct hostapd_data *hapd, const u8 *addr, 00069 const u8 *data, size_t data_len, int encrypt) 00070 { 00071 if (hapd->driver == NULL || hapd->driver->hapd_send_eapol == NULL) 00072 return 0; 00073 return hapd->driver->hapd_send_eapol(hapd->drv_priv, addr, data, 00074 data_len, encrypt, 00075 hapd->own_addr); 00076 } 00077 00078 00079 static int hostapd_set_authorized(struct hostapd_data *hapd, 00080 struct sta_info *sta, int authorized) 00081 { 00082 if (authorized) { 00083 return hostapd_sta_set_flags(hapd, sta->addr, 00084 hostapd_sta_flags_to_drv( 00085 sta->flags), 00086 WPA_STA_AUTHORIZED, ~0); 00087 } 00088 00089 return hostapd_sta_set_flags(hapd, sta->addr, 00090 hostapd_sta_flags_to_drv(sta->flags), 00091 0, ~WPA_STA_AUTHORIZED); 00092 } 00093 00094 00095 static int hostapd_set_key(const char *ifname, struct hostapd_data *hapd, 00096 enum wpa_alg alg, const u8 *addr, int key_idx, 00097 int set_tx, const u8 *seq, size_t seq_len, 00098 const u8 *key, size_t key_len) 00099 { 00100 if (hapd->driver == NULL || hapd->driver->set_key == NULL) 00101 return 0; 00102 return hapd->driver->set_key(ifname, hapd->drv_priv, alg, addr, 00103 key_idx, set_tx, seq, seq_len, key, 00104 key_len); 00105 } 00106 00107 00108 static int hostapd_read_sta_data(struct hostapd_data *hapd, 00109 struct hostap_sta_driver_data *data, 00110 const u8 *addr) 00111 { 00112 if (hapd->driver == NULL || hapd->driver->read_sta_data == NULL) 00113 return -1; 00114 return hapd->driver->read_sta_data(hapd->drv_priv, data, addr); 00115 } 00116 00117 00118 static int hostapd_sta_clear_stats(struct hostapd_data *hapd, const u8 *addr) 00119 { 00120 if (hapd->driver == NULL || hapd->driver->sta_clear_stats == NULL) 00121 return 0; 00122 return hapd->driver->sta_clear_stats(hapd->drv_priv, addr); 00123 } 00124 00125 00126 static int hostapd_set_sta_flags(struct hostapd_data *hapd, 00127 struct sta_info *sta) 00128 { 00129 int set_flags, total_flags, flags_and, flags_or; 00130 total_flags = hostapd_sta_flags_to_drv(sta->flags); 00131 set_flags = WPA_STA_SHORT_PREAMBLE | WPA_STA_WMM | WPA_STA_MFP; 00132 if (((!hapd->conf->ieee802_1x && !hapd->conf->wpa) || 00133 sta->auth_alg == WLAN_AUTH_FT) && 00134 sta->flags & WLAN_STA_AUTHORIZED) 00135 set_flags |= WPA_STA_AUTHORIZED; 00136 flags_or = total_flags & set_flags; 00137 flags_and = total_flags | ~set_flags; 00138 return hostapd_sta_set_flags(hapd, sta->addr, total_flags, 00139 flags_or, flags_and); 00140 } 00141 00142 00143 static int hostapd_set_drv_ieee8021x(struct hostapd_data *hapd, 00144 const char *ifname, int enabled) 00145 { 00146 struct wpa_bss_params params; 00147 os_memset(¶ms, 0, sizeof(params)); 00148 params.ifname = ifname; 00149 params.enabled = enabled; 00150 if (enabled) { 00151 params.wpa = hapd->conf->wpa; 00152 params.ieee802_1x = hapd->conf->ieee802_1x; 00153 params.wpa_group = hapd->conf->wpa_group; 00154 params.wpa_pairwise = hapd->conf->wpa_pairwise; 00155 params.wpa_key_mgmt = hapd->conf->wpa_key_mgmt; 00156 params.rsn_preauth = hapd->conf->rsn_preauth; 00157 } 00158 return hostapd_set_ieee8021x(hapd, ¶ms); 00159 } 00160 00161 00162 static int hostapd_set_radius_acl_auth(struct hostapd_data *hapd, 00163 const u8 *mac, int accepted, 00164 u32 session_timeout) 00165 { 00166 if (hapd->driver == NULL || hapd->driver->set_radius_acl_auth == NULL) 00167 return 0; 00168 return hapd->driver->set_radius_acl_auth(hapd->drv_priv, mac, accepted, 00169 session_timeout); 00170 } 00171 00172 00173 static int hostapd_set_radius_acl_expire(struct hostapd_data *hapd, 00174 const u8 *mac) 00175 { 00176 if (hapd->driver == NULL || 00177 hapd->driver->set_radius_acl_expire == NULL) 00178 return 0; 00179 return hapd->driver->set_radius_acl_expire(hapd->drv_priv, mac); 00180 } 00181 00182 00183 static int hostapd_set_bss_params(struct hostapd_data *hapd, 00184 int use_protection) 00185 { 00186 int ret = 0; 00187 int preamble; 00188 #ifdef CONFIG_IEEE80211N 00189 u8 buf[60], *ht_capab, *ht_oper, *pos; 00190 00191 pos = buf; 00192 ht_capab = pos; 00193 pos = hostapd_eid_ht_capabilities(hapd, pos); 00194 ht_oper = pos; 00195 pos = hostapd_eid_ht_operation(hapd, pos); 00196 if (pos > ht_oper && ht_oper > ht_capab && 00197 hostapd_set_ht_params(hapd, ht_capab + 2, ht_capab[1], 00198 ht_oper + 2, ht_oper[1])) { 00199 wpa_printf(MSG_ERROR, "Could not set HT capabilities " 00200 "for kernel driver"); 00201 ret = -1; 00202 } 00203 00204 #endif /* CONFIG_IEEE80211N */ 00205 00206 if (hostapd_set_cts_protect(hapd, use_protection)) { 00207 wpa_printf(MSG_ERROR, "Failed to set CTS protect in kernel " 00208 "driver"); 00209 ret = -1; 00210 } 00211 00212 if (hapd->iface->current_mode && 00213 hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G && 00214 hostapd_set_short_slot_time(hapd, 00215 hapd->iface->num_sta_no_short_slot_time 00216 > 0 ? 0 : 1)) { 00217 wpa_printf(MSG_ERROR, "Failed to set Short Slot Time option " 00218 "in kernel driver"); 00219 ret = -1; 00220 } 00221 00222 if (hapd->iface->num_sta_no_short_preamble == 0 && 00223 hapd->iconf->preamble == SHORT_PREAMBLE) 00224 preamble = SHORT_PREAMBLE; 00225 else 00226 preamble = LONG_PREAMBLE; 00227 if (hostapd_set_preamble(hapd, preamble)) { 00228 wpa_printf(MSG_ERROR, "Could not set preamble for kernel " 00229 "driver"); 00230 ret = -1; 00231 } 00232 00233 return ret; 00234 } 00235 00236 00237 static int hostapd_set_beacon(struct hostapd_data *hapd, 00238 const u8 *head, size_t head_len, 00239 const u8 *tail, size_t tail_len, int dtim_period, 00240 int beacon_int) 00241 { 00242 if (hapd->driver == NULL || hapd->driver->set_beacon == NULL) 00243 return 0; 00244 return hapd->driver->set_beacon(hapd->drv_priv, 00245 head, head_len, tail, tail_len, 00246 dtim_period, beacon_int); 00247 } 00248 00249 00250 static int hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname) 00251 { 00252 char force_ifname[IFNAMSIZ]; 00253 u8 if_addr[ETH_ALEN]; 00254 return hostapd_if_add(hapd, WPA_IF_AP_VLAN, ifname, NULL, NULL, NULL, 00255 force_ifname, if_addr); 00256 } 00257 00258 static int hostapd_vlan_if_remove(struct hostapd_data *hapd, 00259 const char *ifname) 00260 { 00261 return hostapd_if_remove(hapd, WPA_IF_AP_VLAN, ifname); 00262 } 00263 00264 00265 static int hostapd_set_wds_sta(struct hostapd_data *hapd, const u8 *addr, 00266 int aid, int val) 00267 { 00268 if (hapd->driver == NULL || hapd->driver->set_wds_sta == NULL) 00269 return 0; 00270 return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val); 00271 } 00272 00273 00274 static int hostapd_set_sta_vlan(const char *ifname, struct hostapd_data *hapd, 00275 const u8 *addr, int vlan_id) 00276 { 00277 if (hapd->driver == NULL || hapd->driver->set_sta_vlan == NULL) 00278 return 0; 00279 return hapd->driver->set_sta_vlan(hapd->drv_priv, addr, ifname, 00280 vlan_id); 00281 } 00282 00283 00284 static int hostapd_get_inact_sec(struct hostapd_data *hapd, const u8 *addr) 00285 { 00286 if (hapd->driver == NULL || hapd->driver->get_inact_sec == NULL) 00287 return 0; 00288 return hapd->driver->get_inact_sec(hapd->drv_priv, addr); 00289 } 00290 00291 00292 static int hostapd_sta_deauth(struct hostapd_data *hapd, const u8 *addr, 00293 int reason) 00294 { 00295 if (hapd->driver == NULL || hapd->driver->sta_deauth == NULL) 00296 return 0; 00297 return hapd->driver->sta_deauth(hapd->drv_priv, hapd->own_addr, addr, 00298 reason); 00299 } 00300 00301 00302 static int hostapd_sta_disassoc(struct hostapd_data *hapd, const u8 *addr, 00303 int reason) 00304 { 00305 if (hapd->driver == NULL || hapd->driver->sta_disassoc == NULL) 00306 return 0; 00307 return hapd->driver->sta_disassoc(hapd->drv_priv, hapd->own_addr, addr, 00308 reason); 00309 } 00310 00311 00312 static int hostapd_sta_add(struct hostapd_data *hapd, 00313 const u8 *addr, u16 aid, u16 capability, 00314 const u8 *supp_rates, size_t supp_rates_len, 00315 u16 listen_interval, 00316 const struct ieee80211_ht_capabilities *ht_capab) 00317 { 00318 struct hostapd_sta_add_params params; 00319 00320 if (hapd->driver == NULL) 00321 return 0; 00322 if (hapd->driver->sta_add == NULL) 00323 return 0; 00324 00325 os_memset(¶ms, 0, sizeof(params)); 00326 params.addr = addr; 00327 params.aid = aid; 00328 params.capability = capability; 00329 params.supp_rates = supp_rates; 00330 params.supp_rates_len = supp_rates_len; 00331 params.listen_interval = listen_interval; 00332 params.ht_capabilities = ht_capab; 00333 return hapd->driver->sta_add(hapd->drv_priv, ¶ms); 00334 } 00335 00336 00337 static int hostapd_sta_remove(struct hostapd_data *hapd, const u8 *addr) 00338 { 00339 if (hapd->driver == NULL || hapd->driver->sta_remove == NULL) 00340 return 0; 00341 return hapd->driver->sta_remove(hapd->drv_priv, addr); 00342 } 00343 00344 00345 static int hostapd_set_countermeasures(struct hostapd_data *hapd, int enabled) 00346 { 00347 if (hapd->driver == NULL || 00348 hapd->driver->hapd_set_countermeasures == NULL) 00349 return 0; 00350 return hapd->driver->hapd_set_countermeasures(hapd->drv_priv, enabled); 00351 } 00352 00353 00354 void hostapd_set_driver_ops(struct hostapd_driver_ops *ops) 00355 { 00356 ops->set_ap_wps_ie = hostapd_set_ap_wps_ie; 00357 ops->send_mgmt_frame = hostapd_send_mgmt_frame; 00358 ops->send_eapol = hostapd_send_eapol; 00359 ops->set_authorized = hostapd_set_authorized; 00360 ops->set_key = hostapd_set_key; 00361 ops->read_sta_data = hostapd_read_sta_data; 00362 ops->sta_clear_stats = hostapd_sta_clear_stats; 00363 ops->set_sta_flags = hostapd_set_sta_flags; 00364 ops->set_drv_ieee8021x = hostapd_set_drv_ieee8021x; 00365 ops->set_radius_acl_auth = hostapd_set_radius_acl_auth; 00366 ops->set_radius_acl_expire = hostapd_set_radius_acl_expire; 00367 ops->set_bss_params = hostapd_set_bss_params; 00368 ops->set_beacon = hostapd_set_beacon; 00369 ops->vlan_if_add = hostapd_vlan_if_add; 00370 ops->vlan_if_remove = hostapd_vlan_if_remove; 00371 ops->set_wds_sta = hostapd_set_wds_sta; 00372 ops->set_sta_vlan = hostapd_set_sta_vlan; 00373 ops->get_inact_sec = hostapd_get_inact_sec; 00374 ops->sta_deauth = hostapd_sta_deauth; 00375 ops->sta_disassoc = hostapd_sta_disassoc; 00376 ops->sta_add = hostapd_sta_add; 00377 ops->sta_remove = hostapd_sta_remove; 00378 ops->set_countermeasures = hostapd_set_countermeasures; 00379 } 00380 00381 00382 int hostapd_set_privacy(struct hostapd_data *hapd, int enabled) 00383 { 00384 if (hapd->driver == NULL || hapd->driver->set_privacy == NULL) 00385 return 0; 00386 return hapd->driver->set_privacy(hapd->drv_priv, enabled); 00387 } 00388 00389 00390 int hostapd_set_generic_elem(struct hostapd_data *hapd, const u8 *elem, 00391 size_t elem_len) 00392 { 00393 if (hapd->driver == NULL || hapd->driver->set_generic_elem == NULL) 00394 return 0; 00395 return hapd->driver->set_generic_elem(hapd->drv_priv, elem, elem_len); 00396 } 00397 00398 00399 int hostapd_get_ssid(struct hostapd_data *hapd, u8 *buf, size_t len) 00400 { 00401 if (hapd->driver == NULL || hapd->driver->hapd_get_ssid == NULL) 00402 return 0; 00403 return hapd->driver->hapd_get_ssid(hapd->drv_priv, buf, len); 00404 } 00405 00406 00407 int hostapd_set_ssid(struct hostapd_data *hapd, const u8 *buf, size_t len) 00408 { 00409 if (hapd->driver == NULL || hapd->driver->hapd_set_ssid == NULL) 00410 return 0; 00411 return hapd->driver->hapd_set_ssid(hapd->drv_priv, buf, len); 00412 } 00413 00414 00415 int hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type, 00416 const char *ifname, const u8 *addr, void *bss_ctx, 00417 void **drv_priv, char *force_ifname, u8 *if_addr) 00418 { 00419 if (hapd->driver == NULL || hapd->driver->if_add == NULL) 00420 return -1; 00421 return hapd->driver->if_add(hapd->drv_priv, type, ifname, addr, 00422 bss_ctx, drv_priv, force_ifname, if_addr); 00423 } 00424 00425 00426 int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type, 00427 const char *ifname) 00428 { 00429 if (hapd->driver == NULL || hapd->driver->if_remove == NULL) 00430 return -1; 00431 return hapd->driver->if_remove(hapd->drv_priv, type, ifname); 00432 } 00433 00434 00435 int hostapd_set_ieee8021x(struct hostapd_data *hapd, 00436 struct wpa_bss_params *params) 00437 { 00438 if (hapd->driver == NULL || hapd->driver->set_ieee8021x == NULL) 00439 return 0; 00440 return hapd->driver->set_ieee8021x(hapd->drv_priv, params); 00441 } 00442 00443 00444 int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd, 00445 const u8 *addr, int idx, u8 *seq) 00446 { 00447 if (hapd->driver == NULL || hapd->driver->get_seqnum == NULL) 00448 return 0; 00449 return hapd->driver->get_seqnum(ifname, hapd->drv_priv, addr, idx, 00450 seq); 00451 } 00452 00453 00454 int hostapd_flush(struct hostapd_data *hapd) 00455 { 00456 if (hapd->driver == NULL || hapd->driver->flush == NULL) 00457 return 0; 00458 return hapd->driver->flush(hapd->drv_priv); 00459 } 00460 00461 00462 int hostapd_set_freq(struct hostapd_data *hapd, int mode, int freq, 00463 int channel, int ht_enabled, int sec_channel_offset) 00464 { 00465 struct hostapd_freq_params data; 00466 if (hapd->driver == NULL) 00467 return 0; 00468 if (hapd->driver->set_freq == NULL) 00469 return 0; 00470 os_memset(&data, 0, sizeof(data)); 00471 data.mode = mode; 00472 data.freq = freq; 00473 data.channel = channel; 00474 data.ht_enabled = ht_enabled; 00475 data.sec_channel_offset = sec_channel_offset; 00476 return hapd->driver->set_freq(hapd->drv_priv, &data); 00477 } 00478 00479 int hostapd_set_rts(struct hostapd_data *hapd, int rts) 00480 { 00481 if (hapd->driver == NULL || hapd->driver->set_rts == NULL) 00482 return 0; 00483 return hapd->driver->set_rts(hapd->drv_priv, rts); 00484 } 00485 00486 00487 int hostapd_set_frag(struct hostapd_data *hapd, int frag) 00488 { 00489 if (hapd->driver == NULL || hapd->driver->set_frag == NULL) 00490 return 0; 00491 return hapd->driver->set_frag(hapd->drv_priv, frag); 00492 } 00493 00494 00495 int hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr, 00496 int total_flags, int flags_or, int flags_and) 00497 { 00498 if (hapd->driver == NULL || hapd->driver->sta_set_flags == NULL) 00499 return 0; 00500 return hapd->driver->sta_set_flags(hapd->drv_priv, addr, total_flags, 00501 flags_or, flags_and); 00502 } 00503 00504 00505 int hostapd_set_rate_sets(struct hostapd_data *hapd, int *supp_rates, 00506 int *basic_rates, int mode) 00507 { 00508 if (hapd->driver == NULL || hapd->driver->set_rate_sets == NULL) 00509 return 0; 00510 return hapd->driver->set_rate_sets(hapd->drv_priv, supp_rates, 00511 basic_rates, mode); 00512 } 00513 00514 00515 int hostapd_set_country(struct hostapd_data *hapd, const char *country) 00516 { 00517 if (hapd->driver == NULL || 00518 hapd->driver->set_country == NULL) 00519 return 0; 00520 return hapd->driver->set_country(hapd->drv_priv, country); 00521 } 00522 00523 00524 int hostapd_set_cts_protect(struct hostapd_data *hapd, int value) 00525 { 00526 if (hapd->driver == NULL || hapd->driver->set_cts_protect == NULL) 00527 return 0; 00528 return hapd->driver->set_cts_protect(hapd->drv_priv, value); 00529 } 00530 00531 00532 int hostapd_set_preamble(struct hostapd_data *hapd, int value) 00533 { 00534 if (hapd->driver == NULL || hapd->driver->set_preamble == NULL) 00535 return 0; 00536 return hapd->driver->set_preamble(hapd->drv_priv, value); 00537 } 00538 00539 00540 int hostapd_set_short_slot_time(struct hostapd_data *hapd, int value) 00541 { 00542 if (hapd->driver == NULL || hapd->driver->set_short_slot_time == NULL) 00543 return 0; 00544 return hapd->driver->set_short_slot_time(hapd->drv_priv, value); 00545 } 00546 00547 00548 int hostapd_set_tx_queue_params(struct hostapd_data *hapd, int queue, int aifs, 00549 int cw_min, int cw_max, int burst_time) 00550 { 00551 if (hapd->driver == NULL || hapd->driver->set_tx_queue_params == NULL) 00552 return 0; 00553 return hapd->driver->set_tx_queue_params(hapd->drv_priv, queue, aifs, 00554 cw_min, cw_max, burst_time); 00555 } 00556 00557 00558 int hostapd_valid_bss_mask(struct hostapd_data *hapd, const u8 *addr, 00559 const u8 *mask) 00560 { 00561 if (hapd->driver == NULL || hapd->driver->valid_bss_mask == NULL) 00562 return 1; 00563 return hapd->driver->valid_bss_mask(hapd->drv_priv, addr, mask); 00564 } 00565 00566 00567 struct hostapd_hw_modes * 00568 hostapd_get_hw_feature_data(struct hostapd_data *hapd, u16 *num_modes, 00569 u16 *flags) 00570 { 00571 if (hapd->driver == NULL || 00572 hapd->driver->get_hw_feature_data == NULL) 00573 return NULL; 00574 return hapd->driver->get_hw_feature_data(hapd->drv_priv, num_modes, 00575 flags); 00576 } 00577 00578 00579 int hostapd_driver_commit(struct hostapd_data *hapd) 00580 { 00581 if (hapd->driver == NULL || hapd->driver->commit == NULL) 00582 return 0; 00583 return hapd->driver->commit(hapd->drv_priv); 00584 } 00585 00586 00587 int hostapd_set_ht_params(struct hostapd_data *hapd, 00588 const u8 *ht_capab, size_t ht_capab_len, 00589 const u8 *ht_oper, size_t ht_oper_len) 00590 { 00591 if (hapd->driver == NULL || hapd->driver->set_ht_params == NULL || 00592 ht_capab == NULL || ht_oper == NULL) 00593 return 0; 00594 return hapd->driver->set_ht_params(hapd->drv_priv, 00595 ht_capab, ht_capab_len, 00596 ht_oper, ht_oper_len); 00597 } 00598 00599 00600 int hostapd_drv_none(struct hostapd_data *hapd) 00601 { 00602 return hapd->driver && os_strcmp(hapd->driver->name, "none") == 0; 00603 } 00604 00605 00606 int hostapd_driver_scan(struct hostapd_data *hapd, 00607 struct wpa_driver_scan_params *params) 00608 { 00609 if (hapd->driver && hapd->driver->scan2) 00610 return hapd->driver->scan2(hapd->drv_priv, params); 00611 return -1; 00612 } 00613 00614 00615 struct wpa_scan_results * hostapd_driver_get_scan_results( 00616 struct hostapd_data *hapd) 00617 { 00618 if (hapd->driver && hapd->driver->get_scan_results2) 00619 return hapd->driver->get_scan_results2(hapd->drv_priv); 00620 return NULL; 00621 }