18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPA Supplicant - iPhone/iPod touch Apple80211 driver interface 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2007, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 58d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This program is free software; you can redistribute it and/or modify 68d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * it under the terms of the GNU General Public License version 2 as 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * published by the Free Software Foundation. 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * license. 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * See README and COPYING for more details. 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define Boolean __DummyBoolean 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <CoreFoundation/CoreFoundation.h> 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#undef Boolean 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "driver.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eloop.h" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "MobileApple80211.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpa_driver_iphone_data { 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *ctx; 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Apple80211Ref wireless_ctx; 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CFArrayRef scan_results; 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ctrl_power; 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const void * cfdict_get_key_str(CFDictionaryRef dict, const char *key) 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const void *res; 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, key, 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt kCFStringEncodingMacRoman); 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (str == NULL) 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = CFDictionaryGetValue(dict, str); 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CFRelease(str); 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_iphone_get_ssid(void *priv, u8 *ssid) 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_iphone_data *drv = priv; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CFDataRef data; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int err, len; 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err = Apple80211CopyValue(drv->wireless_ctx, APPLE80211_VALUE_SSID, 0, 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &data); 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (err != 0) { 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "iPhone: Apple80211CopyValue(SSID) " 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed: %d", err); 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = CFDataGetLength(data); 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > 32) { 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CFRelease(data); 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ssid, CFDataGetBytePtr(data), len); 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CFRelease(data); 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_iphone_get_bssid(void *priv, u8 *bssid) 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_iphone_data *drv = priv; 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CFStringRef data; 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int err; 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int a1, a2, a3, a4, a5, a6; 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err = Apple80211CopyValue(drv->wireless_ctx, APPLE80211_VALUE_BSSID, 0, 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &data); 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (err != 0) { 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "iPhone: Apple80211CopyValue(BSSID) " 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed: %d", err); 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sscanf(CFStringGetCStringPtr(data, kCFStringEncodingMacRoman), 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%x:%x:%x:%x:%x:%x", &a1, &a2, &a3, &a4, &a5, &a6); 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid[0] = a1; 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid[1] = a2; 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid[2] = a3; 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid[3] = a4; 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid[4] = a5; 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid[5] = a6; 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CFRelease(data); 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_driver_iphone_scan_timeout(void *eloop_ctx, void *timeout_ctx) 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL); 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_iphone_scan(void *priv, const u8 *ssid, size_t ssid_len) 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_iphone_data *drv = priv; 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int err; 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->scan_results) { 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CFRelease(drv->scan_results); 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->scan_results = NULL; 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err = Apple80211Scan(drv->wireless_ctx, &drv->scan_results, NULL); 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (err) { 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "iPhone: Apple80211Scan failed: %d", 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err); 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(0, 0, wpa_driver_iphone_scan_timeout, drv, 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->ctx); 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_iphone_get_scan_results(void *priv, 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_result *results, 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t max_size) 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_iphone_data *drv = priv; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i, num; 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->scan_results == NULL) 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num = CFArrayGetCount(drv->scan_results); 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num > max_size) 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num = max_size; 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(results, 0, num * sizeof(struct wpa_scan_result)); 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num; i++) { 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_result *res = &results[i]; 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CFDictionaryRef dict = 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CFArrayGetValueAtIndex(drv->scan_results, i); 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CFDataRef data; 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CFStringRef str; 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CFNumberRef num; 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int val; 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data = cfdict_get_key_str(dict, "SSID"); 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data) { 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->ssid_len = CFDataGetLength(data); 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res->ssid_len > 32) 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->ssid_len = 32; 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res->ssid, CFDataGetBytePtr(data), 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->ssid_len); 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt str = cfdict_get_key_str(dict, "BSSID"); 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (str) { 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int a1, a2, a3, a4, a5, a6; 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sscanf(CFStringGetCStringPtr( 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt str, kCFStringEncodingMacRoman), 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%x:%x:%x:%x:%x:%x", 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &a1, &a2, &a3, &a4, &a5, &a6); 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->bssid[0] = a1; 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->bssid[1] = a2; 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->bssid[2] = a3; 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->bssid[3] = a4; 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->bssid[4] = a5; 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->bssid[5] = a6; 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num = cfdict_get_key_str(dict, "CAPABILITIES"); 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num) { 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (CFNumberGetValue(num, kCFNumberSInt32Type, &val)) 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->caps = val; 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num = cfdict_get_key_str(dict, "CHANNEL"); 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num) { 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (CFNumberGetValue(num, kCFNumberSInt32Type, &val)) 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->freq = 2407 + val * 5; 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num = cfdict_get_key_str(dict, "RSSI"); 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num) { 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (CFNumberGetValue(num, kCFNumberSInt32Type, &val)) 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->level = val; 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num = cfdict_get_key_str(dict, "NOISE"); 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num) { 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (CFNumberGetValue(num, kCFNumberSInt32Type, &val)) 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->noise = val; 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data = cfdict_get_key_str(dict, "IE"); 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data) { 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *ptr = (u8 *) CFDataGetBytePtr(data); 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len = CFDataGetLength(data); 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos = ptr, *end = ptr + len; 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos + 2 < end) { 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 2 + pos[1] > end) 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[0] == WLAN_EID_RSN && 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos[1] <= SSID_MAX_WPA_IE_LEN) { 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res->rsn_ie, pos, 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2 + pos[1]); 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->rsn_ie_len = 2 + pos[1]; 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos[1] > 4 && pos[2] == 0x00 && 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos[3] == 0x50 && pos[4] == 0xf2 && 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos[5] == 0x01) { 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res->wpa_ie, pos, 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2 + pos[1]); 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->wpa_ie_len = 2 + pos[1]; 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = pos + 2 + pos[1]; 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return num; 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_driver_iphone_assoc_timeout(void *eloop_ctx, void *timeout_ctx) 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_iphone_data *drv = eloop_ctx; 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 bssid[ETH_ALEN]; 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_driver_iphone_get_bssid(drv, bssid) != 0) { 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(1, 0, wpa_driver_iphone_assoc_timeout, 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv, drv->ctx); 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_event(timeout_ctx, EVENT_ASSOC, NULL); 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_iphone_associate( 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *priv, struct wpa_driver_associate_params *params) 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_iphone_data *drv = priv; 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i, num, err; 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t ssid_len; 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CFDictionaryRef bss = NULL; 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * TODO: Consider generating parameters instead of just using an entry 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * from scan results in order to support ap_scan=2. 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->scan_results == NULL) { 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "iPhone: No scan results - cannot " 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "associate"); 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num = CFArrayGetCount(drv->scan_results); 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num; i++) { 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CFDictionaryRef dict = 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CFArrayGetValueAtIndex(drv->scan_results, i); 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CFDataRef data; 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data = cfdict_get_key_str(dict, "SSID"); 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data == NULL) 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid_len = CFDataGetLength(data); 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid_len != params->ssid_len || 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(CFDataGetBytePtr(data), params->ssid, ssid_len) 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt != 0) 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bss = dict; 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bss == NULL) { 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "iPhone: Could not find SSID from scan " 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "results - cannot associate"); 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "iPhone: Trying to associate with a BSS found " 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "from scan results"); 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err = Apple80211Associate(drv->wireless_ctx, bss, NULL); 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (err) { 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "iPhone: Apple80211Associate() failed: " 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%d", err); 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Driver is actually already associated; report association from an 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eloop callback. 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_driver_iphone_assoc_timeout, drv, drv->ctx); 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(0, 0, wpa_driver_iphone_assoc_timeout, drv, 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->ctx); 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_iphone_set_key(void *priv, wpa_alg alg, const u8 *addr, 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int key_idx, int set_tx, const u8 *seq, 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t seq_len, const u8 *key, 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t key_len) 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * TODO: Need to either support configuring PMK for 4-way handshake or 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * PTK for TKIP/CCMP. 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_iphone_get_capa(void *priv, struct wpa_driver_capa *capa) 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(capa, 0, sizeof(*capa)); 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt capa->key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA | 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_DRIVER_CAPA_KEY_MGMT_WPA2 | 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK | 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK; 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt capa->enc = WPA_DRIVER_CAPA_ENC_WEP40 | WPA_DRIVER_CAPA_ENC_WEP104 | 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_DRIVER_CAPA_ENC_TKIP | WPA_DRIVER_CAPA_ENC_CCMP; 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt capa->auth = WPA_DRIVER_AUTH_OPEN | WPA_DRIVER_AUTH_SHARED | 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_DRIVER_AUTH_LEAP; 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt capa->flags = WPA_DRIVER_FLAGS_4WAY_HANDSHAKE; 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void * wpa_driver_iphone_init(void *ctx, const char *ifname) 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_iphone_data *drv; 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int err; 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char power; 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CFStringRef name; 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CFDictionaryRef dict; 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv = os_zalloc(sizeof(*drv)); 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv == NULL) 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->ctx = ctx; 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err = Apple80211Open(&drv->wireless_ctx); 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (err) { 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "iPhone: Apple80211Open failed: %d", 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err); 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(drv); 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name = CFStringCreateWithCString(kCFAllocatorDefault, ifname, 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt kCFStringEncodingISOLatin1); 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (name == NULL) { 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "iPhone: ifname -> CFString failed"); 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Apple80211Close(drv->wireless_ctx); 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(drv); 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err = Apple80211BindToInterface(drv->wireless_ctx, name); 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CFRelease(name); 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (err) { 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "iPhone: Apple80211BindToInterface " 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed: %d", err); 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Apple80211Close(drv->wireless_ctx); 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(drv); 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err = Apple80211GetPower(drv->wireless_ctx, &power); 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (err) 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "iPhone: Apple80211GetPower failed: %d", 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err); 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "iPhone: Power=%d", power); 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!power) { 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->ctrl_power = 1; 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err = Apple80211SetPower(drv->wireless_ctx, 1); 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (err) { 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "iPhone: Apple80211SetPower " 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed: %d", err); 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Apple80211Close(drv->wireless_ctx); 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(drv); 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err = Apple80211GetInfoCopy(drv->wireless_ctx, &dict); 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (err == 0) { 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CFShow(dict); 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CFRelease(dict); 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Apple80211GetInfoCopy: %d\n", err); 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return drv; 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_driver_iphone_deinit(void *priv) 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_iphone_data *drv = priv; 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int err; 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_driver_iphone_scan_timeout, drv, drv->ctx); 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_driver_iphone_assoc_timeout, drv, drv->ctx); 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->ctrl_power) { 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "iPhone: Power down the interface"); 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err = Apple80211SetPower(drv->wireless_ctx, 0); 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (err) { 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "iPhone: Apple80211SetPower(0) " 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed: %d", err); 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err = Apple80211Close(drv->wireless_ctx); 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (err) { 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "iPhone: Apple80211Close failed: %d", 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err); 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->scan_results) 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CFRelease(drv->scan_results); 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(drv); 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst struct wpa_driver_ops wpa_driver_iphone_ops = { 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt .name = "iphone", 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt .desc = "iPhone/iPod touch Apple80211 driver", 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt .get_ssid = wpa_driver_iphone_get_ssid, 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt .get_bssid = wpa_driver_iphone_get_bssid, 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt .init = wpa_driver_iphone_init, 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt .deinit = wpa_driver_iphone_deinit, 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt .scan = wpa_driver_iphone_scan, 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt .get_scan_results = wpa_driver_iphone_get_scan_results, 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt .associate = wpa_driver_iphone_associate, 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt .set_key = wpa_driver_iphone_set_key, 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt .get_capa = wpa_driver_iphone_get_capa, 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 467