0

I have an android client device that will attempt to connect to a bluetooth-enabled server and transmit data to it. So far, it's been working great except for one hitch: whenever I want to reconnect to the server after the connection was terminated, the server does not detect that a request for connection was sent by the client. If I turn off and on the bluetooth radio, and then attempt to reconnect, everything works normally. What am I doing wrong?

Here's the main Class

package org.team2180.scoutingServer;
import java.io.IOException;

import javax.bluetooth.*;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.io.StreamConnectionNotifier;

import org.json.JSONObject;

import javax.bluetooth.UUID;
public class Server {

    public static final UUID serviceUUID = new UUID("94f39d297d6d437d973bfba39e49d4ee", false);
    public static String connectionString = "btspp://localhost:" + serviceUUID.toString() +";name=ProblemServer";
    static LocalDevice locDev;
    public static final JSONObject DATA = new JSONObject();
    public static void main(String[] args) {
        try {

            locDev = LocalDevice.getLocalDevice();
            System.out.println("Local Device: '" + locDev.getFriendlyName()+"' @ "+locDev.getBluetoothAddress());
            StreamConnectionNotifier streamConnNot = startServer();
            startListening(streamConnNot);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static StreamConnectionNotifier startServer() throws Exception {
        if(serverStarted){return null;}
        boolean isNowDiscoverable = locDev.setDiscoverable(DiscoveryAgent.GIAC);
        System.out.println("Local Device Discoverable: "+Boolean.toString(isNowDiscoverable));
        System.out.println("Local Device URI: "+connectionString);

        StreamConnectionNotifier streamConnNot = (StreamConnectionNotifier) Connector.open(connectionString);
        System.out.println("Server: Created, waiting for clients . . . ");
        return streamConnNot;
    }

    public static void startListening(StreamConnectionNotifier streamConnNot) throws IOException {
        while(true) {
            StreamConnection connection = streamConnNot.acceptAndOpen();
            Thread connectedThread = new Thread(new ConnectionHandler(connection, TEAM_DATA));
            System.out.println("Sever: found a client, placed on thread:" + connectedThread.getId());
            connectedThread.start();
        }
    }
}

I handle each connection with its own thread based on this Class, exchanging an initial byte to determine how to handle the connection (send data to the device's database, get data from the device's database)

package org.team2180.scoutingServer;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Iterator;

import javax.microedition.io.StreamConnection;
import javax.bluetooth.RemoteDevice;
import org.json.*;

public class ConnectionHandler implements Runnable {
    final StreamConnection connection;
    final JSONObject TEAM_DATA;
    RemoteDevice remDev;
    String deviceIndex;
    public ConnectionHandler(StreamConnection connection,JSONObject TEAM_DATA) {
        this.connection = connection;
        this.TEAM_DATA = TEAM_DATA;
        try {
            this.remDev = RemoteDevice.getRemoteDevice(connection);
            this.deviceIndex = remDev.getFriendlyName(true)+'@'+remDev.getBluetoothAddress();
        } catch (IOException e) {
            this.remDev = null;
            this.deviceIndex = null;
        }
    }

    @Override
    public void run() {
        try {
            OutputStream out = connection.openOutputStream();
            InputStream in = connection.openInputStream();
            PrintWriter pWriter = new PrintWriter(new OutputStreamWriter(out));
            BufferedReader bReader = new BufferedReader(new InputStreamReader(in)); 

            int handshake = in.read();
            if(handshake==1) {
                System.out.println(deviceIndex+" will now inform you of TOP SECRET_INFO");
                updateDatabase(remDev, pWriter, bReader);
                System.out.println(deviceIndex+" >\n"+ TEAM_DATA.getJSONObject(deviceIndex).getInt("entryCount"));
      }
        } catch (Exception e) {
            System.out.println(deviceIndex+"'s thread is terminating BADLY!");
            try {connection.close();} catch (IOException e1) {e1.printStackTrace();}
            return;
        }
        System.out.println(deviceIndex+"'s thread is terminating!");
        return;
    }

    public void updateDatabase(RemoteDevice remDev, PrintWriter ex, BufferedReader in) throws IOException, JSONException {
        //OK!
        ex.write(1);
        ex.flush();
        char[] charData = new char[8192];

        in.read(charData);
        String data = new String(charData);

        connection.close();
    //Continue doing other things with data
    .
    .
    .

Here is the Android client code to connect to the server.It is not a thread, and does block, however, this is intentional so that the user waits before leaving the connection radius

sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String text = gatherData();
                try{
                    bS = getSockToServer();
                    bS.connect();
                    OutputStream bsO = bS.getOutputStream();
                    InputStream bsI = bS.getInputStream();
                    bsO.write(1);//Code upload
                    bsO.flush();

                    Log.d("sendButton.onClick","sent condition code 1");

                    int handRespond = (int)bsI.read();

                    Log.d("recieved",handRespond+"");

                    if(handRespond == 1){
                        bsO.write(text.getBytes("UTF-8"));
                        bsO.flush();
                    }

                }catch(Exception e){
                    Log.e("sendButton.onClick",e.toString());
                    try{
                        bS.close();
                    }catch(IOException ioE){
                        Log.e("sendButton.onClick{SNC}",e.toString());
                    }
                }
            }
        });

My final goal would be to handle multiple devices at once (hence the usage of threads) and not have to reset the radio every time a device needs to reconnect.

My code extremely crude; I have only been working with bluecove (and bluetooth in general) for two weeks. Any advice/tricks are appreciated!

Max N
  • 1
  • 2

1 Answers1

0

I can't relive i didn't see this before.

I need to close the socket clientside.

Whoops.

Max N
  • 1
  • 2