0

Cross post with https://stackoverflow.com/questions/52596484/connect-android-and-pi-3-via-network-socket-using-pi-3-as-an-access-point, please delete if this isn't allowed.

My plan here is to create an access point on the Pi 3 using the interface wlan0 which has been setup using hostapd. I run the command hostapd /etc/hostapd/hostapd.conf to start up the network and then I want to connect to it with the Android and setup a socket.

Currently, the network enables on the Pi 3 without issue, but creating the socket on Android is throwing

java.net.ConnectException: failed to connect to /192.168.42.1 (port 80) after 500ms: connect failed: ENETUNREACH (Network is unreachable).

I am using the IP of Pi's wlan0 to create my socket as you can see (on Android code). I will post the output of the Pi's Python script as well as some information about the network.

I have the following Python 3 code on my Pi 3 (server):

import socket
import os

os.system('hostapd /etc/hostapd/hostapd.conf &')
print('started access point service')

serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind(('192.168.42.1', 80))
serversocket.listen(1)

connection, address = serversocket.accept()

b = connection.recv(1024)
print(b)

serversocket.close()
connection.shutdown(socket.SHUT_WR)
connection.close()

Android code regarding the wifi socket connection (client). Joins the network using its' SSID:

        // enable Wifi
        wifiManager.setWifiEnabled(true);

        // connect to the network access point created by the Pi 3
        WifiConfiguration wifiConfiguration = new WifiConfiguration();
        wifiConfiguration.SSID = "\"" + blackBoxSSID + "\"";
        wifiConfiguration.preSharedKey = "\"" + blackBoxNetworkPassword + "\"";
        wifiConfiguration.status = WifiConfiguration.Status.ENABLED;
        wifiConfiguration.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
        wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);

        int netID = wifiManager.addNetwork(wifiConfiguration);
        if (netID == -1) {
            netID = getExistingNetworkID(wifiConfiguration.SSID);
        }

        wifiManager.disconnect();
        wifiManager.enableNetwork(netID, true);
        wifiManager.reconnect();

        WifiInfo wifiInfo = wifiManager.getConnectionInfo();

        Log.d(TAG, "current netID " + netID + ", current SSID " + wifiInfo.getSSID());
        Log.d(TAG, "current IP of wifi device: " + wifiInfo.getIpAddress() + ", HW address: " + wifiInfo.getMacAddress());

        // start the server socket process
        startServerSocket();

Helper functions:

    private void startServerSocket() {
            Log.i(TAG, "Starting server socket thread");
            Thread serverSocketThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Socket socket = new Socket();
                        socket.bind(null);
                        socket.connect(new InetSocketAddress("192.168.42.1", 80), 500);
                        DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
                        dataOutputStream.writeBytes("Hello black box");
                        dataOutputStream.writeBytes("Hello black box");
                        dataOutputStream.writeBytes("Hello black box");
                        dataOutputStream.writeBytes("Hello black box");
                        dataOutputStream.writeBytes("Hello black box");
                        dataOutputStream.writeBytes("Hello black box");
                        socket.close();
                    } catch (IOException e) {
                        Log.e(TAG, "Error creating ServerSocket and Socket object:", e);
                    }
                }
            });
            serverSocketThread.start();
            Log.d(TAG, "started server socket thread");
        }

and

private int getExistingNetworkID(String SSID) {
        WifiManager wifiManager = (WifiManager) mContext.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        List<WifiConfiguration> configuredNetworks = wifiManager.getConfiguredNetworks();
        if (configuredNetworks != null) {
            for (WifiConfiguration existingConfig : configuredNetworks) {
                if (existingConfig.SSID.equals(SSID)) {
                    return existingConfig.networkId;
                }
            }
        }
        return -1;
    }

here's the manifest file:

<!-- Wifi/Internet-related permissions -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
    <uses-permission android:name="android.permission.INTERNET"/>

The Android code returns

current netID 617, current SSID "NetworkName" current IP of wifi device: 0, HW address: <hw address of something but not wlan0>, which means the correct network is connected without issue.

The Python code returns

started access point service
Configuration file: /etc/hostapd/hostapd.conf
Failed to create interface mon.wlan0: -95 (Operation not supported)
wlan0: interface state UNINITIALIZED->COUNTRY_UPDATE
wlan0: Could not connect to kernel driver
Using interface wlan0 with hwaddr <wlan0 hw address> and ssid "NetworkName"
listening on port 80
wlan0: interface state COUNTRY_UPDATE->ENABLED
wlan0: AP-ENABLED 

and all wifi devices I have can see the network and connect using the password.

For more info here is the hostapd.conf file:

interface=wlan0
#driver=nl80211
ssid=Coriolis
country_code=CA
hw_mode=g
channel=6
wmm_enabled=0
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=password123
wpa_key_mgmt=WPA-PSK
wpa_group_rekey=86400
ieee80211n=1
wpa_pairwise=TKIP
rsn_pairwise=CCMP
wme_enabled=1

sorry about the indentation inside some of the code snippets, using the {} code button puts this in and I can't seem to get rid of it without removing the code formatting.

Edit:

Here is the contents of /etc/dnsmasq.conf:

interface=wlan0 dhcp-range=192.168.42.2,192.168.42.4,255.255.255.0,24h

dnsmasq and hostapd services are both active (running)

If I manually go and select Wifi then connect using the WPA password, the device associates then disassociates with the Pi 3, then reads AP-STA-CONNECTED with pairwise key handshake completed (RSN). So clearly my Android code is doing something weird. But doing this crashes the app with a RuntimeException; unable to instantiate receiver (wifiReceiver - which doesn't exist) and ClassNotFoundException: didn't find class (wifiReceiver) on path: DexPathList. It seems like this is a completely internal call as well, there are no tracebacks to my actual code.

  • tl;dr but have scanned the question but could not find what is the specific problem with Raspberry Pi. I only read that it works as expected as access point but Android has a problem. Is Android also running on a RasPi? – Ingo Oct 1 '18 at 22:00
0

PART 1:

I was creating working on a .NET app through my FreeNAS server and my router started filtering out my connections because it thought my server was under attack; unfortunately I cannot remember the specific reason. I cannot tell you how much frustration this caused me.

Check your router log and see if it is sensing an attack from your "access point". There may be a firewall or something else blocking the connection as well, I don't know what kind of firewalls would be in effect here.

PART 2:

Log.d(TAG, "started server socket thread");

Does this ever log anything

And I am not familiar with this threading stuff, but won't "startServerSocket" just exit - shouldn't there be some kind of block or asynchronous wait?

(Note: I would have posted a comment, but it says I am too new)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.