/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package com.mozilla.SUTAgentAndroid;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.Formatter;
import java.util.List;
import java.util.regex.Pattern;
import java.util.Timer;

import com.mozilla.SUTAgentAndroid.service.ASMozStub;
import com.mozilla.SUTAgentAndroid.service.DoCommand;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.net.Uri;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.WifiLock;
import android.os.BatteryManager;
import android.os.Build;
import android.os.Build.VERSION;
import android.os.Bundle;
import android.os.Handler;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class SUTAgentAndroid extends Activity
    {
    final Handler mHandler = new Handler();

    private static final Pattern IPV4_PATTERN = Pattern.compile("^(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}$");

    public static final int START_PRG = 1959;
    MenuItem mExitMenuItem;
    Timer timer = null;

    public static String sUniqueID = null;
    public static String sLocalIPAddr = null;
    public static String sACStatus = null;
    public static String sPowerStatus = null;
    public static int    nChargeLevel = 0;
    public static int    nBatteryTemp = 0;
    public static long   nCreateTimeMillis = System.currentTimeMillis();
    public static String sTestRoot = "";

    String lineSep = System.getProperty("line.separator");
    public PrintWriter dataOut = null;

    private static boolean bNetworkingStarted = false;
    private static String RegSvrIPAddr = "";
    private static String RegSvrIPPort = "";
    private static String HardwareID = "";
    private static String Pool = "";
    private static String Abi = "";
    private static String sRegString = "";
    private static boolean LogCommands = false;

    private WifiLock wl = null;

    private BroadcastReceiver battReceiver = null;

    private TextView  tv = null;

    public boolean onCreateOptionsMenu(Menu menu)
        {
        mExitMenuItem = menu.add("Exit");
        mExitMenuItem.setIcon(android.R.drawable.ic_menu_close_clear_cancel);
        return super.onCreateOptionsMenu(menu);
        }

    public boolean onMenuItemSelected(int featureId, MenuItem item)
        {
        if (item == mExitMenuItem)
            {
            finish();
            }
        return super.onMenuItemSelected(featureId, item);
        }

    public static String getRegSvrIPAddr()
        {
        return(RegSvrIPAddr);
        }

    public void pruneCommandLog(String datestamp, String testroot)
        {

        String today = "";
        String yesterday = "";

        // test root can be null (if getTestRoot fails), handle that:
        if (testroot == null) {
            testroot = "";
        }

        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS");
            Date dateObj = sdf.parse(datestamp);
            SimpleDateFormat sdf_file = new SimpleDateFormat("yyyy-MM-dd");

            today     = sdf_file.format(dateObj);
            yesterday = sdf_file.format(new Date(dateObj.getTime() - 1000*60*60*24));
        } catch (ParseException pe) {}

        File dir = new File(testroot);

        if (!dir.isDirectory())
            return;

        File [] files = dir.listFiles();
        if (files == null)
            return;

        for (int iter = 0; iter < files.length; iter++) {
            String fName = files[iter].getName();
            if (fName.endsWith("sutcommands.txt")) {
                if (fName.endsWith(today + "-sutcommands.txt") || fName.endsWith(yesterday + "-sutcommands.txt"))
                    continue;

                if (files[iter].delete())
                    Log.i("SUTAgentAndroid", "Deleted old command logfile: " + files[iter]);
                else
                    Log.e("SUTAgentAndroid", "Unable to delete old command logfile: " + files[iter]);
            }
        }
        }

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
        {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        fixScreenOrientation();

        DoCommand dc = new DoCommand(getApplication());

        Log.i("SUTAgentAndroid", dc.prgVersion);
        dc.FixDataLocalPermissions();

        // Get configuration settings from "ini" file
        File dir = getFilesDir();
        File iniFile = new File(dir, "SUTAgent.ini");
        String sIniFile = iniFile.getAbsolutePath();

        String lc = dc.GetIniData("General", "LogCommands", sIniFile);
        if (lc != "" && Integer.parseInt(lc) == 1) {
            SUTAgentAndroid.LogCommands = true;
        }
        SUTAgentAndroid.RegSvrIPAddr = dc.GetIniData("Registration Server", "IPAddr", sIniFile);
        SUTAgentAndroid.RegSvrIPPort = dc.GetIniData("Registration Server", "PORT", sIniFile);
        SUTAgentAndroid.HardwareID = dc.GetIniData("Registration Server", "HARDWARE", sIniFile);
        SUTAgentAndroid.Pool = dc.GetIniData("Registration Server", "POOL", sIniFile);
        SUTAgentAndroid.sTestRoot = dc.GetIniData("Device", "TestRoot", sIniFile);
        SUTAgentAndroid.Abi = android.os.Build.CPU_ABI;
        log(dc, "onCreate");

        dc.SetTestRoot(SUTAgentAndroid.sTestRoot);

        Log.i("SUTAgentAndroid", "Test Root: " + SUTAgentAndroid.sTestRoot);

        tv = (TextView) this.findViewById(R.id.Textview01);

        if (getLocalIpAddress() == null)
            setUpNetwork(sIniFile);

        String macAddress = "Unknown";
        if (android.os.Build.VERSION.SDK_INT > 8) {
            try {
                NetworkInterface iface = NetworkInterface.getByInetAddress(InetAddress.getAllByName(getLocalIpAddress())[0]);
                if (iface != null)
                    {
                        byte[] mac = iface.getHardwareAddress();
                        if (mac != null)
                            {
                                StringBuilder sb = new StringBuilder();
                                Formatter f = new Formatter(sb);
                                for (int i = 0; i < mac.length; i++)
                                    {
                                        f.format("%02x%s", mac[i], (i < mac.length - 1) ? ":" : "");
                                    }
                                macAddress = sUniqueID = sb.toString();
                            }
                    }
            }
            catch (UnknownHostException ex) {}
            catch (SocketException ex) {}
        }
        else
            {
                // Fall back to getting info from wifiman on older versions of Android,
                // which don't support the NetworkInterface interface
                WifiManager wifiMan = (WifiManager)getSystemService(Context.WIFI_SERVICE);
                if (wifiMan != null)
                    {
                        WifiInfo wifi = wifiMan.getConnectionInfo();
                        if (wifi != null)
                            macAddress = wifi.getMacAddress();
                        if (macAddress != null)
                            sUniqueID = macAddress;
                    }
            }

        if (sUniqueID == null)
            {
            BluetoothAdapter ba = BluetoothAdapter.getDefaultAdapter();
            if ((ba != null) && (ba.isEnabled() != true))
                {
                ba.enable();
                while(ba.getState() != BluetoothAdapter.STATE_ON)
                    {
                    try {
                        Thread.sleep(1000);
                        }
                    catch (InterruptedException e)
                        {
                        e.printStackTrace();
                        }
                    }

                sUniqueID = ba.getAddress();

                ba.disable();
                while(ba.getState() != BluetoothAdapter.STATE_OFF)
                    {
                    try {
                        Thread.sleep(1000);
                        }
                    catch (InterruptedException e)
                        {
                        e.printStackTrace();
                        }
                    }
                }
            else
                {
                if (ba != null)
                    {
                    sUniqueID = ba.getAddress().toLowerCase();
                    }
                }
            }

        if (sUniqueID == null)
            {
            TelephonyManager mTelephonyMgr = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
            if (mTelephonyMgr != null)
                {
                sUniqueID = mTelephonyMgr.getDeviceId();
                if (sUniqueID == null)
                    {
                    sUniqueID = "0011223344556677";
                    }
                }
            }

        String hwid = getHWID(this);

        sLocalIPAddr = getLocalIpAddress();
        Toast.makeText(getApplication().getApplicationContext(), "SUTAgent [" + sLocalIPAddr + "] ...", Toast.LENGTH_LONG).show();

        String sConfig = dc.prgVersion + lineSep;
        sConfig += "Test Root: " + sTestRoot + lineSep;
        sConfig += "Unique ID: " + sUniqueID + lineSep;
        sConfig += "HWID: " + hwid + lineSep;
        sConfig += "ABI: " + Abi + lineSep;
        sConfig += "OS Info" + lineSep;
        sConfig += "\t" + dc.GetOSInfo() + lineSep;
        sConfig += "Screen Info" + lineSep;
        int [] xy = dc.GetScreenXY();
        sConfig += "\t Width: " + xy[0] + lineSep;
        sConfig += "\t Height: " + xy[1] + lineSep;
        sConfig += "Memory Info" + lineSep;
        sConfig += "\t" + dc.GetMemoryInfo() + lineSep;
        sConfig += "Network Info" + lineSep;
        sConfig += "\tMac Address: " + macAddress + lineSep;
        sConfig += "\tIP Address: " + sLocalIPAddr + lineSep;

        displayStatus(sConfig);

        sRegString = "NAME=" + sUniqueID;
        sRegString += "&IPADDR=" + sLocalIPAddr;
        sRegString += "&CMDPORT=" + 20701;
        sRegString += "&DATAPORT=" + 20700;
        sRegString += "&OS=Android-" + dc.GetOSInfo();
        sRegString += "&SCRNWIDTH=" + xy[0];
        sRegString += "&SCRNHEIGHT=" + xy[1];
        sRegString += "&BPP=8";
        sRegString += "&MEMORY=" + dc.GetMemoryConfig();
        sRegString += "&HARDWARE=" + HardwareID;
        sRegString += "&POOL=" + Pool;
        sRegString += "&ABI=" + Abi;

        String sTemp = Uri.encode(sRegString,"=&");
        sRegString = "register " + sTemp;

        pruneCommandLog(dc.GetSystemTime(), dc.GetTestRoot());

        if (!bNetworkingStarted)
            {
            Thread thread = new Thread(null, doStartService, "StartServiceBkgnd");
            thread.start();
            bNetworkingStarted = true;

            Thread thread2 = new Thread(null, doRegisterDevice, "RegisterDeviceBkgnd");
            thread2.start();
            }

        monitorBatteryState();

        // If we are returning from an update let'em know we're back
        Thread thread3 = new Thread(null, doUpdateCallback, "UpdateCallbackBkgnd");
        thread3.start();

        final Button goButton = (Button) findViewById(R.id.Button01);
        goButton.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                finish();
                }
            });
        }

    private class UpdateStatus implements Runnable {
        public String sText = "";

        UpdateStatus(String sStatus) {
            sText = sStatus;
        }

        public void run() {
            displayStatus(sText);
        }
    }

    public synchronized void displayStatus(String sStatus) {
        String sTVText = (String) tv.getText();
        sTVText += sStatus;
        tv.setText(sTVText);
    }

    public void fixScreenOrientation()
        {
        setRequestedOrientation((getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) ?
                                ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        }

    protected void onActivityResult(int requestCode, int resultCode, Intent data)
        {
        if (requestCode == START_PRG)
            {
               Toast.makeText(getApplication().getApplicationContext(), "SUTAgent startprg finished ...", Toast.LENGTH_LONG).show();
            }
        }

    @Override
    public void onDestroy()
        {
        DoCommand dc = new DoCommand(getApplication());
        super.onDestroy();
        if (isFinishing())
            {
            log(dc, "onDestroy - finishing");
            Intent listenerSvc = new Intent(this, ASMozStub.class);
            listenerSvc.setAction("com.mozilla.SUTAgentAndroid.service.LISTENER_SERVICE");
            stopService(listenerSvc);
            bNetworkingStarted = false;

            unregisterReceiver(battReceiver);

            if (wl != null)
                wl.release();

            System.exit(0);
            }
        else
            {
            log(dc, "onDestroy - not finishing");
            }
        }

    private void logMemory(String caller)
        {
        DoCommand dc = new DoCommand(getApplication());
        if (dc != null)
            {
            log(dc, caller);
            log(dc, dc.GetMemoryInfo());
            String procInfo = dc.GetProcessInfo();
            if (procInfo != null)
                {
                String lines[] = procInfo.split("\n");
                for (String line : lines) 
                    {
                    if (line.contains("mozilla"))
                        {
                        log(dc, line);
                        String words[] = line.split("\t");
                        if ((words != null) && (words.length > 1))
                            {
                            log(dc, dc.StatProcess(words[1]));
                            }
                        }
                    }
                }
            }
        else
            {
            Log.e("SUTAgentAndroid", "logMemory: unable to log to file!");
            }
        }

    @Override
    public void onLowMemory()
        {
        System.gc();
        logMemory("onLowMemory");
        }

    @Override
    public void onTrimMemory(int level)
        {
        System.gc();
        logMemory("onTrimMemory"+level);
        }

    private void monitorBatteryState()
        {
        battReceiver = new BroadcastReceiver()
            {
            public void onReceive(Context context, Intent intent)
                {
                StringBuilder sb = new StringBuilder();

                int rawlevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); // charge level from 0 to scale inclusive
                int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); // Max value for charge level
                int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
                int health = intent.getIntExtra(BatteryManager.EXTRA_HEALTH, -1);
                boolean present = intent.getBooleanExtra(BatteryManager.EXTRA_PRESENT, false);
                int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); //0 if the device is not plugged in; 1 if plugged into an AC power adapter; 2 if plugged in via USB.
//                int voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1); // voltage in millivolts
                nBatteryTemp = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1); // current battery temperature in tenths of a degree Centigrade
//                String technology = intent.getStringExtra(BatteryManager.EXTRA_TECHNOLOGY);

                nChargeLevel = -1;  // percentage, or -1 for unknown
                if (rawlevel >= 0 && scale > 0)
                    {
                    nChargeLevel = (rawlevel * 100) / scale;
                    }

                if (plugged > 0)
                    sACStatus = "ONLINE";
                else
                    sACStatus = "OFFLINE";

                if (present == false)
                    sb.append("NO BATTERY");
                else
                    {
                    if (nChargeLevel < 10)
                        sb.append("Critical");
                    else if (nChargeLevel < 33)
                        sb.append("LOW");
                    else if (nChargeLevel > 80)
                        sb.append("HIGH");
                    }

                if (BatteryManager.BATTERY_HEALTH_OVERHEAT == health)
                    {
                    sb.append("Overheated ");
                    sb.append((((float)(nBatteryTemp))/10));
                    sb.append("(C)");
                    }
                else
                    {
                    switch(status)
                        {
                        case BatteryManager.BATTERY_STATUS_UNKNOWN:
                            // old emulator; maybe also when plugged in with no battery
                            if (present == true)
                                sb.append(" UNKNOWN");
                            break;
                        case BatteryManager.BATTERY_STATUS_CHARGING:
                            sb.append(" CHARGING");
                            break;
                        case BatteryManager.BATTERY_STATUS_DISCHARGING:
                            sb.append(" DISCHARGING");
                            break;
                        case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
                            sb.append(" NOTCHARGING");
                            break;
                        case BatteryManager.BATTERY_STATUS_FULL:
                            sb.append(" FULL");
                            break;
                        default:
                            if (present == true)
                                sb.append("Unknown");
                            break;
                        }
                    }

                sPowerStatus = sb.toString();
                }
            };

        IntentFilter battFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
        registerReceiver(battReceiver, battFilter);
        }

    public boolean setUpNetwork(String sIniFile)
        {
        boolean    bRet = false;
        int    lcv    = 0;
        int    lcv2 = 0;
        WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
        WifiConfiguration wc = new WifiConfiguration();
        DoCommand tmpdc = new DoCommand(getApplication());

        String ssid = tmpdc.GetIniData("Network Settings", "SSID", sIniFile);
        String auth = tmpdc.GetIniData("Network Settings", "AUTH", sIniFile);
        String encr = tmpdc.GetIniData("Network Settings", "ENCR", sIniFile);
        String key = tmpdc.GetIniData("Network Settings", "KEY", sIniFile);
        String eap = tmpdc.GetIniData("Network Settings", "EAP", sIniFile);
        String adhoc = tmpdc.GetIniData("Network Settings", "ADHOC", sIniFile);

        Toast.makeText(getApplication().getApplicationContext(), "Starting and configuring network", Toast.LENGTH_LONG).show();
/*
        ContentResolver cr = getContentResolver();
        int nRet;
        try {
            nRet = Settings.System.getInt(cr, Settings.System.WIFI_USE_STATIC_IP);
            String foo2 = "" + nRet;
        } catch (SettingNotFoundException e1) {
            e1.printStackTrace();
        }
*/
/*
        wc.SSID = "\"Mozilla-Build\"";
        wc.preSharedKey  = "\"MozillaBuildQA500\"";
        wc.hiddenSSID = true;
        wc.status = WifiConfiguration.Status.ENABLED;
        wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
        wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
        wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
        wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
        wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
        wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
        wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
*/
        wc.SSID = "\"" + ssid + "\"";
//        wc.SSID = "\"Mozilla-G\"";
//        wc.SSID = "\"Mozilla\"";

        if (auth.contentEquals("wpa2"))
            {
            wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
            wc.preSharedKey  = null;
            }

        if (encr.contentEquals("aes"))
            {
            wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
            wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            }

        if (eap.contentEquals("peap"))
            {
            wc.eap.setValue("PEAP");
            wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
            wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
            }

        wc.status = WifiConfiguration.Status.ENABLED;

        if (!wifi.isWifiEnabled())
            wifi.setWifiEnabled(true);

        while(wifi.getWifiState() != WifiManager.WIFI_STATE_ENABLED)
            {
            Thread.yield();
            if (++lcv > 10000)
                return(bRet);
            }

        wl = wifi.createWifiLock(WifiManager.WIFI_MODE_FULL, "SUTAgent");
        if (wl != null)
            wl.acquire();

        WifiConfiguration    foo = null;
        int                    nNetworkID = -1;

        List<WifiConfiguration> connsLst =  wifi.getConfiguredNetworks();
        int nConns = connsLst.size();
        for (int i = 0; i < nConns; i++)
            {

            foo = connsLst.get(i);
            if (foo.SSID.equalsIgnoreCase(wc.SSID))
                {
                nNetworkID = foo.networkId;
                wc.networkId = foo.networkId;
                break;
                }
            }

        int res;

        if (nNetworkID != -1)
            {
            res = wifi.updateNetwork(wc);
            }
        else
            {
            res = wifi.addNetwork(wc);
            }

        Log.d("WifiPreference", "add Network returned " + res );

        boolean b = wifi.enableNetwork(res, true);
        Log.d("WifiPreference", "enableNetwork returned " + b );

        wifi.saveConfiguration();

        WifiInfo wi = wifi.getConnectionInfo();
        SupplicantState ss = wi.getSupplicantState();

        lcv = 0;
        lcv2 = 0;

        while (ss.compareTo(SupplicantState.COMPLETED) != 0)
            {
            try {
                Thread.sleep(1000);
                }
            catch (InterruptedException e)
                {
                e.printStackTrace();
                }

            if (wi != null)
                wi = null;
            if (ss != null)
                ss = null;
            wi = wifi.getConnectionInfo();
            ss = wi.getSupplicantState();
            if (++lcv > 60)
                {
                if (++lcv2 > 5)
                    {
                    Toast.makeText(getApplication().getApplicationContext(), "Unable to start and configure network", Toast.LENGTH_LONG).show();
                    return(bRet);
                    }
                else
                    {
                    Toast.makeText(getApplication().getApplicationContext(), "Resetting wifi interface", Toast.LENGTH_LONG).show();
                    if (wl != null)
                        wl.release();
                    wifi.setWifiEnabled(false);
                    while(wifi.getWifiState() != WifiManager.WIFI_STATE_DISABLED)
                        {
                        Thread.yield();
                        }

                    wifi.setWifiEnabled(true);
                    while(wifi.getWifiState() != WifiManager.WIFI_STATE_ENABLED)
                        {
                        Thread.yield();
                        }
                    b = wifi.enableNetwork(res, true);
                    Log.d("WifiPreference", "enableNetwork returned " + b );
                    if (wl != null)
                        wl.acquire();
                    lcv = 0;
                    }
                }
            }

        lcv = 0;
        while(getLocalIpAddress() == null)
            {
            if (++lcv > 10000)
                return(bRet);
            }

        Toast.makeText(getApplication().getApplicationContext(), "Network started and configured", Toast.LENGTH_LONG).show();
        bRet = true;

        return(bRet);
        }

    // If there is an update.info file callback the server and send the status
    private Runnable doUpdateCallback = new Runnable() {
        public void run() {
            DoCommand dc = new DoCommand(getApplication());
            String sRet = dc.UpdateCallBack("update.info");
            if (sRet.length() > 0) {
                if (sRet.contains("ok")) {
                    sRet = "Callback Server contacted successfully" + lineSep;
                } else if (sRet.contains("Nothing to do")) {
                    sRet = "";
                } else {
                    sRet = "Callback Server NOT contacted successfully" + lineSep;
                }
            }
            if (sRet.length() > 0)
                mHandler.post(new UpdateStatus(sRet));
            dc = null;
        }
    };

    // registers with the reg server defined in the SUTAgent.ini file
    private Runnable doRegisterDevice = new Runnable() {
        public void run() {
            DoCommand dc = new DoCommand(getApplication());
            String sRet = "";
            if (RegSvrIPAddr.length() > 0) {
                String sRegRet = dc.RegisterTheDevice(RegSvrIPAddr, RegSvrIPPort, sRegString);
                if (sRegRet.contains("ok")) {
                    sRet += "Registered with testserver" + lineSep;
                    sRet += "\tIPAddress: " + RegSvrIPAddr + lineSep;
                    if (RegSvrIPPort.length() > 0)
                        sRet += "\tPort: " + RegSvrIPPort + lineSep;
                } else {
                    sRet += "Not registered with testserver" + lineSep;
                }
            } else {
                sRet += "Not registered with testserver" + lineSep;
            }

        if (sRet.length() > 0)
            mHandler.post(new UpdateStatus(sRet));
        dc = null;
        }
    };

    // this starts the listener service for the command and data channels
    private Runnable doStartService = new Runnable()
        {
        public void run()
            {
            Intent listenerService = new Intent();
            listenerService.setAction("com.mozilla.SUTAgentAndroid.service.LISTENER_SERVICE");
            startService(listenerService);
            }
        };

    static String sHWID = null;
    public static String getHWID(Context cx) {
        if (sHWID != null)
            return sHWID;

        // If we're on SDK version > 8, use Build.SERIAL
        if (android.os.Build.VERSION.SDK_INT > 8) {
            sHWID = android.os.Build.SERIAL;
        }

        if (sHWID != null)
            return sHWID;

        // Otherwise, try from the telephony manager
        TelephonyManager mTelephonyMgr = (TelephonyManager) cx.getSystemService(TELEPHONY_SERVICE);
        if (mTelephonyMgr != null) {
            sHWID = mTelephonyMgr.getDeviceId();
        }

        if (sHWID != null)
            return sHWID;

        // Otherwise, try WIFI_SERVICE and use the wifi manager
        WifiManager wifiMan = (WifiManager) cx.getSystemService(Context.WIFI_SERVICE);
        if (wifiMan != null) {
            WifiInfo wifi = wifiMan.getConnectionInfo();
            if (wifi != null) {
                sHWID = "wifimac" + wifi.getMacAddress();
            }
        }

        if (sHWID != null)
            return sHWID;

        sHWID = "0011223344556677";

        return sHWID;
    }

    public static boolean isIPv4Address(final String input) {
        return IPV4_PATTERN.matcher(input).matches();
    }

    public static InetAddress getLocalInetAddress() throws SocketException
        {
        for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();)
            {
            NetworkInterface intf = en.nextElement();
            for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();)
                {
                InetAddress inetAddress = enumIpAddr.nextElement();
                if (!inetAddress.isLoopbackAddress() && isIPv4Address(inetAddress.getHostAddress()))
                    {
                        return inetAddress;
                    }
                }
            }

        return null;
        }

    public String getLocalIpAddress()
        {
        try {
            InetAddress inetAddress = getLocalInetAddress();
            if (inetAddress != null)
                return inetAddress.getHostAddress().toString();
            }
        catch (SocketException ex)
            {
            Toast.makeText(getApplication().getApplicationContext(), ex.toString(), Toast.LENGTH_LONG).show();
            }
        return null;
        }

    public static void log(DoCommand dc, String message)
        {
        Log.i("SUTAgentAndroid", message);

        if (SUTAgentAndroid.LogCommands == false)
            {
            return;
            }

        if (message == null)
            {
            Log.e("SUTAgentAndroid", "bad arguments in log()!");
            return;
            }
        String fileDateStr = "00";
        String testRoot = dc.GetTestRoot();
        String datestamp = dc.GetSystemTime();
        if (testRoot == null || datestamp == null)
            {
            Log.e("SUTAgentAndroid", "Unable to get testRoot or datestamp in log!");
            return;
            }


        try 
            {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS");
            Date dateStr = sdf.parse(datestamp);
            SimpleDateFormat sdf_file = new SimpleDateFormat("yyyy-MM-dd");
            fileDateStr = sdf_file.format(dateStr);
            } 
        catch (ParseException pe) {}
        String logFile = testRoot + "/" + fileDateStr + "-sutcommands.txt";
        PrintWriter pw = null;
        try 
            {
            pw = new PrintWriter(new FileWriter(logFile, true));
            pw.println(datestamp + " : " + message);
            } 
            catch (IOException ioe) 
            {
                Log.e("SUTAgentAndroid", "exception with file writer on: " + logFile);
            } 
            finally 
            {
                if (pw != null)
                {
                    pw.close();
                }
            }

        }
}
