2 * wpadebug - wpa_supplicant and Wi-Fi debugging app for Android
3 * Copyright (c) 2013, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
9 package w1.fi.wpadebug;
11 import java.util.ArrayList;
12 import java.util.ListIterator;
13 import java.io.BufferedReader;
14 import java.io.InputStreamReader;
15 import java.io.InputStream;
16 import java.io.IOException;
18 import android.app.ListActivity;
19 import android.app.ActionBar;
20 import android.content.Intent;
21 import android.os.Bundle;
22 import android.view.View;
23 import android.view.Menu;
24 import android.view.MenuItem;
25 import android.widget.ListView;
26 import android.widget.ArrayAdapter;
27 import android.widget.Toast;
28 import android.widget.AdapterView.AdapterContextMenuInfo;
38 public Credential(String entry)
40 String fields[] = entry.split("\t");
41 id = Integer.parseInt(fields[0]);
42 if (fields.length > 1)
46 if (fields.length > 2)
50 if (fields.length > 3 && fields[3].length() > 0)
54 if (fields.length > 4 && fields[4].length() > 0)
60 public Credential(int _id, String _username, String _realm, String _domain,
72 public String toString()
74 String res = id + " - " + username + "@" + realm;
76 res += " (domain=" + domain + ")";
78 res += " (imsi=" + imsi + ")";
83 public class WpaCredActivity extends ListActivity
85 private static final String TAG = "wpadebug";
86 static final int CRED_EDIT_REQ = 0;
87 private ArrayList<Credential> mList;
88 private ArrayAdapter<Credential> mListAdapter;
91 public void onCreate(Bundle savedInstanceState)
93 super.onCreate(savedInstanceState);
95 mList = new ArrayList<Credential>();
97 String res = run("LIST_CREDS");
99 Toast.makeText(this, "Could not get credential list",
100 Toast.LENGTH_LONG).show();
105 String creds[] = res.split("\n");
106 for (String cred: creds) {
107 if (Character.isDigit(cred.charAt(0)))
108 mList.add(new Credential(cred));
111 mListAdapter = new ArrayAdapter<Credential>(this, android.R.layout.simple_list_item_1, mList);
113 setListAdapter(mListAdapter);
114 registerForContextMenu(getListView());
116 ActionBar abar = getActionBar();
120 public boolean onCreateOptionsMenu(Menu menu)
122 menu.add(0, 0, 0, "Add credential");
126 protected void onActivityResult(int requestCode, int resultCode,
129 if (requestCode == CRED_EDIT_REQ) {
130 if (resultCode != RESULT_OK)
133 String username = data.getStringExtra("username");
135 String realm = data.getStringExtra("realm");
137 String domain = data.getStringExtra("domain");
138 if (domain != null && domain.length() == 0)
141 String imsi = data.getStringExtra("imsi");
142 if (imsi != null && imsi.length() == 0)
145 String password = data.getStringExtra("password");
146 if (password != null && password.length() == 0)
149 String res = run("ADD_CRED");
150 if (res == null || res.contains("FAIL")) {
151 Toast.makeText(this, "Failed to add credential",
152 Toast.LENGTH_LONG).show();
157 String lines[] = res.split("\n");
158 for (String line: lines) {
159 if (Character.isDigit(line.charAt(0))) {
160 id = Integer.parseInt(line);
166 Toast.makeText(this, "Failed to add credential (invalid id)",
167 Toast.LENGTH_LONG).show();
171 if (!set_cred_quoted(id, "username", username) ||
172 !set_cred_quoted(id, "realm", realm) ||
174 !set_cred_quoted(id, "password", password)) ||
175 (domain != null && !set_cred_quoted(id, "domain", domain)) ||
176 (imsi != null && !set_cred_quoted(id, "imsi", imsi))) {
177 run("REMOVE_CRED " + id);
178 Toast.makeText(this, "Failed to set credential field",
179 Toast.LENGTH_LONG).show();
183 mListAdapter.add(new Credential(id, username, realm, domain, imsi));
188 public boolean onOptionsItemSelected(MenuItem item)
190 if (item.getTitle().equals("Add credential")) {
191 startActivityForResult(new Intent(this, WpaCredEditActivity.class),
198 public void onCreateContextMenu(android.view.ContextMenu menu, View v,
199 android.view.ContextMenu.ContextMenuInfo menuInfo)
201 menu.add(0, v.getId(), 0, "Delete");
205 public boolean onContextItemSelected(MenuItem item)
207 if (item.getTitle().equals("Delete")) {
208 AdapterContextMenuInfo info =
209 (AdapterContextMenuInfo) item.getMenuInfo();
210 Credential cred = (Credential) getListAdapter().getItem(info.position);
211 String res = run("REMOVE_CRED " + cred.id);
212 if (res == null || !res.contains("OK")) {
213 Toast.makeText(this, "Failed to delete credential",
214 Toast.LENGTH_LONG).show();
216 mListAdapter.remove(cred);
219 return super.onContextItemSelected(item);
223 protected void onListItemClick(ListView l, View v, int position, long id)
225 Credential item = (Credential) getListAdapter().getItem(position);
226 Toast.makeText(this, "Credential selected: " + item,
227 Toast.LENGTH_SHORT).show();
230 private String run(String cmd)
233 Process proc = Runtime.getRuntime().exec(new String[]{"/system/bin/mksh-su", "-c", "wpa_cli " + cmd});
234 BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
235 StringBuffer output = new StringBuffer();
237 char[] buffer = new char[1024];
238 while ((read = reader.read(buffer)) > 0)
239 output.append(buffer, 0, read);
242 return output.toString();
243 } catch (IOException e) {
244 Toast.makeText(this, "Could not run command",
245 Toast.LENGTH_LONG).show();
247 } catch (InterruptedException e) {
248 throw new RuntimeException(e);
252 private boolean set_cred(int id, String field, String value)
254 String res = run("SET_CRED " + id + " " + field + " " + value);
255 return res != null && res.contains("OK");
258 private boolean set_cred_quoted(int id, String field, String value)
260 String value2 = "'\"" + value + "\"'";
261 return set_cred(id, field, value2);