fihdi
fihdi

Reputation: 155

Creating a VOIP app that works within a Wifi Hotspot

With this code:

public class MainActivity extends AppCompatActivity {

    int clientAmount = 0;
    int localPort = 0;
    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);
        try {

            AudioManager audio = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
            audio.setMode(AudioManager.MODE_IN_COMMUNICATION);
            final AudioGroup m_AudioGroup = new AudioGroup();
            m_AudioGroup.setMode(AudioGroup.MODE_NORMAL);

            final AudioStream m_AudioStream = new AudioStream(getAPAddress());

            int localPort = m_AudioStream.getLocalPort();


            Log.d("VOIP","Local Port: "+ Integer.toString(localPort));

            m_AudioStream.setCodec(AudioCodec.PCMU);
            m_AudioStream.setMode(RtpStream.MODE_NORMAL);

            findViewById(R.id.connectButton).setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    String remoteAddress = "";
                    String remotePort = "";

                    try {
                        remoteAddress = ((TextView) findViewById(R.id.ipField)).getText().toString();
                        //String remoteAddress = fetchIPs().get(0);
                        remotePort = ((EditText) findViewById(R.id.portField)).getText().toString();

                    }catch(Exception e){
                        ((TextView) findViewById(R.id.statusLabel)).setText("Enter Correct Information");
                    }
                    //Log.d("VOIP", fetchIPs().get(0));

                    try {
                        m_AudioStream.associate(InetAddress.getByName(remoteAddress), Integer.parseInt(remotePort));

                        Log.d("VOIP","Succesfully connected to " + remoteAddress);

                    } catch (Exception e) {
                        ((TextView) findViewById(R.id.statusLabel)).setText("Exception with associating");
                        Log.d("VOIP","Exception with associating");
                        Log.d("VOIP", e.getMessage());
                    }
                    m_AudioStream.join(m_AudioGroup);
                }
            });

            findViewById(R.id.DisconnectButton).setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    m_AudioStream.release();
                }
            });

        } catch (Exception e) {
            Log.e("VOIP", "Exception when setting up the Audiostream!");
            e.printStackTrace();
        }
    }


    public InetAddress getAPAddress() {
        try {
            for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
                NetworkInterface intf = en.nextElement();

                if(intf.getName().equals("ap0")) {

                    for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                        InetAddress inetAddress = enumIpAddr.nextElement();

                        for(int i = 0; i<intf.getInterfaceAddresses().size(); i++){

                            if( intf.getInterfaceAddresses().get(i).getAddress() instanceof Inet4Address){

                                Log.d("VOIP", "IP: " + intf.getInterfaceAddresses().get(i).getAddress() + " NetworkInterface: " + intf.getName());
                                return (Inet4Address) intf.getInterfaceAddresses().get(i).getAddress();
                            }
                        }
                    }
                }
            }
        } catch (SocketException ex) {
            Log.e("VOIP", ex.toString());
        }
        return null;
    }

    public InetAddress getWLANAddress() {
        InetAddress result = null;

        try {
            for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
                NetworkInterface intf = en.nextElement();


                if(intf.getName().equals("wlan0")) {
                    for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                        InetAddress inetAddress = enumIpAddr.nextElement();
                        InterfaceAddress a = intf.getInterfaceAddresses().get(1);

                        for(int i = 0; i<intf.getInterfaceAddresses().size(); i++){

                            if( intf.getInterfaceAddresses().get(i).getAddress() instanceof Inet4Address){
                                Log.d("VOIP", "IP: " + intf.getInterfaceAddresses().get(i).getAddress() + " NetworkInterface: " + intf.getName());
                                result =  intf.getInterfaceAddresses().get(i).getAddress();
                            }
                        }
                        if (!inetAddress.isLoopbackAddress()) {
                            return result;
                        }
                    }
                }
            }
        } catch (SocketException ex) {
            Log.e("VOIP", ex.toString());
        }

        Log.d("VOIP"," Access Point nor Wlan accessible");

        return null;

    }

}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/lblLocalPort"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/localPort" />

    <EditText
        android:id="@+id/ipField"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:ems="10"
        android:hint="@string/iPHint"
        android:inputType="phone" />

    <EditText
        android:id="@+id/portField"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:ems="10"
        android:hint="@string/portHint"
        android:inputType="number">

        <requestFocus />
    </EditText>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp">

        <Button
            android:id="@+id/connectButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/connect" />

        <Button
            android:id="@+id/DisconnectButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/Disconnect" />

        <Button
            android:id="@+id/fetchButtons"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Fetch IPs" />
    </LinearLayout>

    <TextView
        android:id="@+id/statusLabel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView" />
</LinearLayout>

I want to create a peer to peer Walkie Talkie app that allows me to transmit audio between two devices. One device, call it HostDevice, creates a WiFi access point (hotspot), and the other device, ClientDevice, connects to it. My understanding is, that with HostDevice, I initiate the AudioStream with the InetAddress of the access point network interface (called "ap0") and with ClientDevice I initiate the AudioStream with the InetAddress of the wlan network interface ("wlan0"). (Is this correct?) So when I upload the code to HostDevice, I write:

final AudioStream m_AudioStream = new AudioStream(getAPAddress());

and at the ClientDevice's side I have the same code, except I initiate AudioStream like this:

final AudioStream m_AudioStream = new AudioStream(getWLANAddress());

When I enter the IP Address and the port number of the two devices like in the picture below, and press Connect on either device, I get an exception at m_AudioStream.associate(InetAddress.getByName(remoteAddress), Integer.parseInt(remotePort)); And I, obviously, don't hear anything from the speaker from either device. enter image description here

This answer from Murphybro2 says that this is all it takes for two devices to communicate with each other. So where does my understanding break down?

Upvotes: 1

Views: 142

Answers (1)

mail2subhajit
mail2subhajit

Reputation: 1150

Step to check if the VOIP or Peer to Peer application is working

Step 1 : Check if the Audio Stream is captured and processed properly. Print the logs or check the logcat for the specific logs or audio raw dump if possible.

Step 2 : Check if the Audio RTP packets are transmitted to the network and to the proper IP address and port no. pcap file (wireshark /tcpdump tool to sniff) network packets. decode as RTP packets

Step 3 : check if the data received by the receiver is processed properly and rendered with the same configuration as it was captured. Print the logs or check the logcat for the specific logs or audio raw dump if possible.

Please share your observation/results based on the above steps.

Upvotes: 0

Related Questions