1 /* 2 * binder interface for wpa_supplicant daemon 3 * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi> 4 * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com> 5 * 6 * This software may be distributed under the terms of the BSD license. 7 * See README for more details. 8 */ 9 10 #include "supplicant.h" 11 #include "binder_manager.h" 12 13 namespace wpa_supplicant_binder { 14 15 Supplicant::Supplicant(struct wpa_global *global) : wpa_global_(global) {} 16 17 android::binder::Status Supplicant::CreateInterface( 18 const android::os::PersistableBundle ¶ms, 19 android::sp<fi::w1::wpa_supplicant::IIface> *aidl_return) 20 { 21 android::String16 driver, ifname, confname, bridge_ifname; 22 23 /* Check if required Ifname argument is missing */ 24 if (!params.getString(android::String16("Ifname"), &ifname)) 25 return android::binder::Status::fromServiceSpecificError( 26 ERROR_INVALID_ARGS, 27 android::String8("Ifname missing in params.")); 28 /* Retrieve the remaining params from the dictionary */ 29 params.getString(android::String16("Driver"), &driver); 30 params.getString(android::String16("ConfigFile"), &confname); 31 params.getString(android::String16("BridgeIfname"), &bridge_ifname); 32 33 /* 34 * Try to get the wpa_supplicant record for this iface, return 35 * an error if we already control it. 36 */ 37 if (wpa_supplicant_get_iface( 38 wpa_global_, android::String8(ifname).string()) != NULL) 39 return android::binder::Status::fromServiceSpecificError( 40 ERROR_IFACE_EXISTS, 41 android::String8("wpa_supplicant already controls this " 42 "interface.")); 43 44 android::binder::Status status; 45 struct wpa_supplicant *wpa_s = NULL; 46 struct wpa_interface iface; 47 48 os_memset(&iface, 0, sizeof(iface)); 49 iface.driver = os_strdup(android::String8(driver).string()); 50 iface.ifname = os_strdup(android::String8(ifname).string()); 51 iface.confname = os_strdup(android::String8(confname).string()); 52 iface.bridge_ifname = 53 os_strdup(android::String8(bridge_ifname).string()); 54 /* Otherwise, have wpa_supplicant attach to it. */ 55 wpa_s = wpa_supplicant_add_iface(wpa_global_, &iface, NULL); 56 /* The supplicant core creates a corresponding binder object via 57 * BinderManager when |wpa_supplicant_add_iface| is called. */ 58 if (!wpa_s || !wpa_s->binder_object_key) { 59 status = android::binder::Status::fromServiceSpecificError( 60 ERROR_UNKNOWN, 61 android::String8( 62 "wpa_supplicant couldn't grab this interface.")); 63 } else { 64 BinderManager *binder_manager = BinderManager::getInstance(); 65 66 if (!binder_manager || 67 binder_manager->getIfaceBinderObjectByKey( 68 wpa_s->binder_object_key, aidl_return)) 69 status = 70 android::binder::Status::fromServiceSpecificError( 71 ERROR_UNKNOWN, 72 android::String8("wpa_supplicant encountered a " 73 "binder error.")); 74 else 75 status = android::binder::Status::ok(); 76 } 77 os_free((void *)iface.driver); 78 os_free((void *)iface.ifname); 79 os_free((void *)iface.confname); 80 os_free((void *)iface.bridge_ifname); 81 return status; 82 } 83 84 android::binder::Status Supplicant::RemoveInterface(const std::string &ifname) 85 { 86 struct wpa_supplicant *wpa_s; 87 88 wpa_s = wpa_supplicant_get_iface(wpa_global_, ifname.c_str()); 89 if (!wpa_s || !wpa_s->binder_object_key) 90 return android::binder::Status::fromServiceSpecificError( 91 ERROR_IFACE_UNKNOWN, 92 android::String8("wpa_supplicant does not control this " 93 "interface.")); 94 if (wpa_supplicant_remove_iface(wpa_global_, wpa_s, 0)) 95 return android::binder::Status::fromServiceSpecificError( 96 ERROR_UNKNOWN, 97 android::String8( 98 "wpa_supplicant couldn't remove this interface.")); 99 return android::binder::Status::ok(); 100 } 101 102 android::binder::Status Supplicant::GetInterface( 103 const std::string &ifname, 104 android::sp<fi::w1::wpa_supplicant::IIface> *aidl_return) 105 { 106 struct wpa_supplicant *wpa_s; 107 108 wpa_s = wpa_supplicant_get_iface(wpa_global_, ifname.c_str()); 109 if (!wpa_s || !wpa_s->binder_object_key) 110 return android::binder::Status::fromServiceSpecificError( 111 ERROR_IFACE_UNKNOWN, 112 android::String8( 113 "wpa_supplicant does not control this interface.")); 114 115 BinderManager *binder_manager = BinderManager::getInstance(); 116 if (!binder_manager || 117 binder_manager->getIfaceBinderObjectByKey( 118 wpa_s->binder_object_key, aidl_return)) 119 return android::binder::Status::fromServiceSpecificError( 120 ERROR_UNKNOWN, 121 android::String8( 122 "wpa_supplicant encountered a binder error.")); 123 124 return android::binder::Status::ok(); 125 } 126 127 } /* namespace wpa_supplicant_binder */ 128