package info.guardianproject.gilga.radio; import info.guardianproject.gilga.service.GilgaService; import java.lang.reflect.Method; import java.util.Collection; import java.util.HashMap; import java.util.Map; import android.content.Context; import android.net.wifi.p2p.WifiP2pDevice; import android.net.wifi.p2p.WifiP2pDeviceList; import android.net.wifi.p2p.WifiP2pManager; import android.net.wifi.p2p.WifiP2pManager.ActionListener; import android.net.wifi.p2p.WifiP2pManager.Channel; import android.net.wifi.p2p.WifiP2pManager.ChannelListener; import android.net.wifi.p2p.WifiP2pManager.DnsSdServiceResponseListener; import android.net.wifi.p2p.WifiP2pManager.DnsSdTxtRecordListener; import android.net.wifi.p2p.WifiP2pManager.PeerListListener; import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo; import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceRequest; import android.util.Log; public class WifiController { private final static String TAG = "GilgaWifi"; //for WifiP2P mode WifiP2pManager mWifiManager = null; Channel mWifiChannel = null; boolean mWifiEnabled = true; private String mLocalAddressHeader = ""; private GilgaService mService; public void init (GilgaService service) { mService = service; mWifiManager = (WifiP2pManager) mService.getSystemService(Context.WIFI_P2P_SERVICE); mWifiChannel = mWifiManager.initialize(mService, mService.getMainLooper(), new ChannelListener() { @Override public void onChannelDisconnected() { Log.d(GilgaService.TAG,"wifi p2p disconnected"); } }); WifiP2pDnsSdServiceRequest serviceRequest = WifiP2pDnsSdServiceRequest.newInstance(); mWifiManager.addServiceRequest(mWifiChannel, serviceRequest, new ActionListener() { @Override public void onSuccess() { // Success! Log.d(TAG,"SUCCESS: added service request wifi name service"); } @Override public void onFailure(int code) { // Command failed. Check for P2P_UNSUPPORTED, ERROR, or BUSY Log.d(TAG,"FAILURED: added service request wifi name service: " + code); } }); } public void stopWifi () { mWifiManager.stopPeerDiscovery(mWifiChannel, new WifiP2pManager.ActionListener() { @Override public void onSuccess() { Log.d(TAG,"success on stop discover"); } @Override public void onFailure(int reasonCode) { // Code for when the discovery initiation fails goes here. // Alert the user that something went wrong. Log.d(TAG,"FAIL on stop discovery: " + reasonCode); } }); // Add the local service, sending the service info, network channel, // and listener that will be used to indicate success or failure of // the request. mWifiManager.clearLocalServices(mWifiChannel, new ActionListener() { @Override public void onSuccess() { // Command successful! Code isn't necessarily needed here, // Unless you want to update the UI or add logging statements. Log.d(TAG,"SUCCESS: clear local wifi name service"); } @Override public void onFailure(int arg0) { // Command failed. Check for P2P_UNSUPPORTED, ERROR, or BUSY Log.d(TAG,"FAILURE: clear local wifi name service: err=" + arg0); } }); mWifiManager.clearServiceRequests(mWifiChannel, new ActionListener() { @Override public void onSuccess() { // Success! Log.d(TAG,"SUCCESS: clear service request wifi name service"); } @Override public void onFailure(int code) { // Command failed. Check for P2P_UNSUPPORTED, ERROR, or BUSY Log.d(TAG,"FAILURED: clear service request wifi name service: " + code); } }); mWifiManager.cancelConnect(mWifiChannel, new WifiP2pManager.ActionListener() { @Override public void onSuccess() { Log.d(TAG,"success on cancel connect"); } @Override public void onFailure(int reasonCode) { // Code for when the discovery initiation fails goes here. // Alert the user that something went wrong. Log.d(TAG,"FAIL on cancel connect: " + reasonCode); } }); } public void setEnabled (boolean enabled) { mWifiEnabled = enabled; } public void setLocalAddressHeader (String localAddressHeader) { mLocalAddressHeader = localAddressHeader;//shares with BT address to avoid dup messages } /** * this is not reliable, so let's not do it anymore public void setWifiDeviceName (String newDeviceName) { try { ActionListener al = new ActionListener () { @Override public void onFailure(int arg0) { // Log.d(TAG,"could not set wifi device name: " + arg0); } @Override public void onSuccess() { // Log.d(TAG,"set new device name!"); } }; Class c; c = Class.forName("android.net.wifi.p2p.WifiP2pManager"); Method m = c.getMethod("setDeviceName", new Class[] {Channel.class, String.class, ActionListener.class}); Object o = m.invoke(mWifiManager, new Object[]{mWifiChannel,newDeviceName, al}); } catch (Exception e){ Log.e(TAG,"error setting wifi name",e); } }*/ public void getNetworkInfo () { // Connection state changed! We should probably do something about // that. /* NetworkInfo networkInfo = (NetworkInfo) intent .getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO); mWifiManager.requestConnectionInfo(mWifiChannel, new ConnectionInfoListener() { @Override public void onConnectionInfoAvailable(WifiP2pInfo winfo) { } }); */ } public void requestPeers () { // The peer list has changed! We should probably do something about // that. mWifiManager.requestPeers(mWifiChannel, peerListListener); } public void startWifiDiscovery () { if (mWifiEnabled) { mWifiManager.discoverPeers(mWifiChannel, new WifiP2pManager.ActionListener() { @Override public void onSuccess() { // Code for when the discovery initiation is successful goes here. // No services have actually been discovered yet, so this method // can often be left blank. Code for peer discovery goes in the // onReceive method, detailed below. Log.d(TAG,"success on wifi discover"); } @Override public void onFailure(int reasonCode) { // Code for when the discovery initiation fails goes here. // Alert the user that something went wrong. Log.d(TAG,"FAIL on wifi discovery: " + reasonCode); } }); discoverWifiService(); } } private PeerListListener peerListListener = new PeerListListener() { @Override public void onPeersAvailable(WifiP2pDeviceList peerList) { Collection<WifiP2pDevice> deviceList = peerList.getDeviceList(); for (WifiP2pDevice device : deviceList) { boolean trusted = false; //not sure how to do this with wifi if (!GilgaService.mapToNickname(device.deviceAddress).startsWith(mLocalAddressHeader)) //not me mService.processInboundMessage(device.deviceName,device.deviceAddress,trusted); } } }; public void updateWifiStatus(String status) { //setWifiDeviceName(' ' + status); // Create a string map containing information about your service. Map record = new HashMap(); record.put("status", status); // Service information. Pass it an instance name, service type // _protocol._transportlayer , and the map containing // information other devices will want once they connect to this one. WifiP2pDnsSdServiceInfo serviceInfo = WifiP2pDnsSdServiceInfo.newInstance("_test", "_presence._tcp", record); mWifiManager.clearLocalServices(mWifiChannel, new ActionListener() { @Override public void onSuccess() { // Command successful! Code isn't necessarily needed here, // Unless you want to update the UI or add logging statements. Log.d(TAG,"SUCCESS: clear local wifi name service"); } @Override public void onFailure(int arg0) { // Command failed. Check for P2P_UNSUPPORTED, ERROR, or BUSY Log.d(TAG,"FAILURE: clear local wifi name service: err=" + arg0); } }); // Add the local service, sending the service info, network channel, // and listener that will be used to indicate success or failure of // the request. mWifiManager.addLocalService(mWifiChannel, serviceInfo, new ActionListener() { @Override public void onSuccess() { // Command successful! Code isn't necessarily needed here, // Unless you want to update the UI or add logging statements. Log.d(TAG,"SUCCESS: enabled local wifi name service"); } @Override public void onFailure(int arg0) { // Command failed. Check for P2P_UNSUPPORTED, ERROR, or BUSY Log.d(TAG,"FAILURE: enabled local wifi name service: err=" + arg0); } }); } private void discoverWifiService() { DnsSdTxtRecordListener txtListener = new DnsSdTxtRecordListener() { @Override /* Callback includes: * fullDomain: full domain name: e.g "printer._ipp._tcp.local." * record: TXT record dta as a map of key/value pairs. * device: The device running the advertised service. */ public void onDnsSdTxtRecordAvailable(String fullDomain, Map record, WifiP2pDevice device) { String status = (String)record.get("status"); Log.d(TAG,"got status from wifi DNS: " + device.deviceAddress + " (" + fullDomain + ") " + status); mService.processInboundMessage(device.deviceAddress,status,false); } }; DnsSdServiceResponseListener servListener = new DnsSdServiceResponseListener() { @Override public void onDnsSdServiceAvailable(String instanceName, String registrationType, WifiP2pDevice resourceType) { Log.d(TAG,"SD service available!"); } }; mWifiManager.setDnsSdResponseListeners(mWifiChannel, servListener, txtListener); mWifiManager.discoverServices(mWifiChannel, new ActionListener() { @Override public void onSuccess() { // Success! Log.d(TAG, "discover services!"); } @Override public void onFailure(int code) { // Command failed. Check for P2P_UNSUPPORTED, ERROR, or BUSY if (code == WifiP2pManager.P2P_UNSUPPORTED) { Log.d(TAG, "P2P isn't supported on this device."); mWifiEnabled = false; } } }); } }