(Update: I got a reply from Jouni Malinen on the hostap mailinglist, I
tried his approachm but that doesn't seem to work either. I posted the
message below on the hostap mailinglist as well, since it seems to be
an Android-wpa_supplicant combination problem)

Hello Jouni,

Thanks for the reply. I've tried talking to the Unix domain Socket,
but it doesn't work. It appears to be a permission problem.

You mentioned that Solution 3 should work.
Quote from my previous post; "- Solution 3: Talking directly to the
control interface of wpa_suplicant using Unix domain sockets. I found
that the Android API supplies us with the LocalSocket class for
this. ..."

I have tried 2 ways of connecting to the wpa_supplicant Unix domain
socket(s).

1. From an Android terminal emulator through wpa_cli.
2. I adapted an example Java Android program (original:
http://all4dev.blogspot.com/2009/02/android-localsocket-localserversocket.html).

For clarity: each Android app has its own group and username, for
example <group:user> = app_35:app_35. For each approach I adjusted
wpa_supplicant.conf>ctrl_interface_group to allow an app access to the
domain sockets, for example (ctrl_interface_group=app_35).

Results approach 1 ( From an Android terminal emulator through
wpa_cli. ):
1. I start up the Android terminal emulator and enter the command
wpa_cli -p/data/misc/wifi/sockets/ctrl_wpa_79-0. I get the message:

"Using interface 'tiwlan0'
Could not connect to wpa_supplicant - re-trying"
(The output is the same if I don't add the path to the socket, or
change the path to /data/misc/wifi/sockets.)

Results approaches 2a and 2b:
Next, I tried it from an Android Java program (with the correct
wpa_supplicant.conf.ctrl_interface_group and after
wpa_cli>reconfigure) using 2 slightly different approaches:
a. When I use 'tiwlan0' as LocalSocketAddress, I use an abstract
namespace for the LocalSocket. When I do this I get a 'connection
refused' error message from the Android debug tool logcat.
b. When In use "/data/misc/wifi/sockets/ctrl_wpa_79-0", I use the
Filesystem Namespace. I then get a 'permission denied' error message.
a&b Both throw an IOException at the line "receiver.connect(new
LocalSocketAddress(SOCKET_ADDRESS, NAMESPACE)); " (this happens when
"if socket is in invalid state or the address does not exist.").

So, or I'm doing something wrong, or something goes wrong with the
socket permissions. In the adb shell output the file permissions for
the sockets are set to <group:user> system:wifi.

Below this message you can find the shell output and the Java code.

Thanks for any help in advance.

Kind regards,

Aäron Jansen




***** Extra = ADB shell output showing location of sockets, and
wpa_supplicant.conf *****
C:\Users\ajansen\Desktop\android-sdk-windows\tools>adb root
adbd is already running as root

C:\Users\ajansen\Desktop\android-sdk-windows\tools>adb shell
# cd /data/misc/wifi
cd /data/misc/wifi

# cat wpa_supplicant.conf
cat wpa_supplicant.conf

ctrl_interface=tiwlan0
ctrl_interface_group=app_35
network={
ssid="aaron"
proto=WPA2
key_mgmt=WPA-EAP
eap=PEAP
pairwise=CCMP
}
#

# cd sockets
cd sockets
# pwd
pwd
/data/misc/wifi/sockets
# ls
ls
wpa_ctrl_79-1
wpa_ctrl_79-0
# ls -l
ls -l
srw-rw---- system   wifi              2010-02-23 10:23 wpa_ctrl_79-1
srw-rw---- system   wifi              2010-02-23 10:23 wpa_ctrl_79-0
#


***** Java code *****
package com.example.demolocalsocket;

import java.io.IOException;
import java.io.InputStream;

import android.app.Activity;
import android.net.LocalServerSocket;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

/**
*
* @author Denis Migol
*
*/
public class DemoLocalSocketActivity extends Activity {

    public static String SOCKET_ADDRESS = "tiwlan0";
    public static LocalSocketAddress.Namespace NAMESPACE =
LocalSocketAddress.Namespace.ABSTRACT;

    // background threads use this Handler to post messages to
    // the main application thread
    private final Handler handler = new Handler();

    public class NotificationRunnable implements Runnable {
        private String message = null;

        public void run() {
            if (message != null && message.length() > 0) {
                showNotification(message);
            }
        }

        /**
        * @param message the message to set
        */
        public void setMessage(String message) {
            this.message = message;
        }
    }

    // post this to the Handler when the background thread notifies
    private final NotificationRunnable notificationRunnable = new
NotificationRunnable();

    public void showNotification(String message) {
        Toast.makeText(this, message+ " " + this.handler.toString(),
Toast.LENGTH_LONG).show();
    }

    class SocketListener extends Thread {
        private Handler handler = null;
        private NotificationRunnable runnable = null;

        public SocketListener(Handler handler, NotificationRunnable
runnable) {
            this.handler = handler;
            this.runnable = runnable;
            this.handler.post(this.runnable);
        }

        /**
        * Show UI notification.
        * @param message
        */
        private void showMessage(String message) {
            this.runnable.setMessage(message);
            this.handler.post(this.runnable);
        }

        @Override
        public void run() {
            //showMessage("DEMO: SocketListener started!");
            try {

                //LocalServerSocket server = new
LocalServerSocket(SOCKET_ADDRESS);
                LocalSocket receiver = new LocalSocket();

                receiver.connect(new LocalSocketAddress(SOCKET_ADDRESS,
NAMESPACE));
                showMessage("test");


                InputStream input = receiver.getInputStream();

                while (true) {

                    //LocalSocket receiver = server.accept();
                    if (receiver != null) {

                        // simply for java.util.ArrayList
                        int readed = input.read();
                        showMessage("input.read()");

                        int size = 0;
                        int capacity = 0;
                        byte[] bytes = new byte[capacity];



                        // reading
                        while (readed != -1) {
                            // java.util.ArrayList.Add(E e);
                            capacity = (capacity * 3)/2 + 1;
                            //bytes = Arrays.copyOf(bytes, capacity);
                            byte[] copy = new byte[capacity];
                            System.arraycopy(bytes, 0, copy, 0,
bytes.length);
                            bytes = copy;
                            bytes[size++] = (byte)readed;

                            // read next byte
                            readed = input.read();
                        }

                        showMessage(new String(bytes, 0, size));

                    }

                }
            } catch (IOException e) {
                showMessage("test2");
                Log.e("**************"+getClass().getName(),
e.getMessage());
                //showMessage(e.toString());
            }
        }
    }

    public static void writeSocket(String message) throws IOException
{
        //LocalSocket sender = new LocalSocket();
        //sender.connect(new LocalSocketAddress(SOCKET_ADDRESS,
NAMESPACE));
        //sender.getOutputStream().write(message.getBytes());
        //sender.getOutputStream().close();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        new SocketListener(this.handler,
this.notificationRunnable).start();

        Button send1 = (Button)findViewById(R.id.send_1_button);
        send1.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                try {
                    writeSocket("logoff");
                } catch (IOException e) {
                    Log.e(getClass().getName(), e.getMessage());
                }
            }

        });
    }
}



2010/2/19 Aäron Jansen (Gmail) <aaron.jan...@gmail.com>
Hi,

(I'm new to posting questions on mailing lists. Suggestions on good
posting behaviour are appreciated. :)  )

FYI: I've also posted this issue on the Android Development Google
Group.

This is what I'm trying to achieve: I would like to write an Android
app that is capable of talking to wpa_supplicant. More specifically, I
would like to connect to a WPA2-EAP secured network (with
authentication methods TTLS / PEAP / TLS), but since the device will
be used by several users, the user credentials will be supplied by the
user in my app, instead of by wpa_suplicant.conf. I don't want to
write my own supplicant software, I would like to be able to
communicate with it. (I am able to connect to the network when I
provide the user credentials as well in the /data/misc/wifi/
wpa_supplicant.conf file)

I've looked at several solutions and their problems, and I would like
some advice on them. Maybe I've overlooked something:

- Solution 1: Using the Android Wifi API. Problem: The Android WiFi
API doesn't seem to support TTLS / PEAP / TLS. Strange other thing is:
It appears to support LEAP, but I can't find a way to supply the user
credentials to the WifiConfiguration.

- Solution 2: Letting the app write to /data/misc/wifi/
wpa_supplicant.conf and then reassociating. Problem: I understand from
the API that apps can only write to their own private space or the
external SD store. I've also tried writing to a file with the Terminal
Emulator app. This doesn't work. I can only write wpa_supplicant.conf
in the adb shell with root acces.

- Solution 3: Talking directly to the control interface of
wpa_suplicant using Unix domain sockets. I found that the Android API
supplies us with the LocalSocket class for this. However, I have no
idea how to cummunicate with the wpa_supplicant control interface
domain socket. (I will also post this on a wpa_supplicant forum).

- Solution 4: Using java.lang.Runtime and .Process for running wpa_cli
and communicating with it. Problem: I expect there will be
Manifest.permission conflicts.

- Solution 5: Another option might be to use Android NDK / JNI to be
able to use the helper functions in c that wpa_supplicant provides.
Problem: This might be a solution, but it seems to me that it
complicates matters a lot. And I also wonder if there might be some
Manifest.permission conflicts.

- Solution 6: Finding some open source Java supplicant code and
adapting this. Problem: I haven't found it yet. (My C skills aren't so
good, and it needs to work on Android).

I really need some help on this. Is there somebody with some more
experience on this topic? I hope somebody would be able to enlighten
me by providing some answers or pointers on where to look.

Any help would be greatly appreciated. Thanks in advance,

a2ronus



--
Met vriendelijke groet,

Aäron Jansen

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to