import java.io.*;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.io.*;
import javax.bluetooth.*;
import java.util.*;

/**
* @author test
*/
public class test extends MIDlet implements CommandListener,DiscoveryListener {
      private List activeDevices;
      private List activeServices;
      private Command select,exit;
      private Display display;
      private LocalDevice local=null;
      private DiscoveryAgent agent = null;
      private Vector devicesFound = null;
      private ServiceRecord[] servicesFound = null;
      private String connectionURL = null;
      private Object serviceSearchSemaphore = new Object();

      public void startApp() {
            display = Display.getDisplay(this);
            activeDevices = new List("Active Devices", List.IMPLICIT);
            activeServices = new List("Active Services", List.IMPLICIT);
            select = new Command("Select", Command.OK, 0);
            exit = new Command("Exit", Command.EXIT, 0);
            activeDevices.addCommand(select);
            activeDevices.addCommand(exit);
            activeServices.addCommand(exit);
            activeDevices.setCommandListener(this);
            activeServices.setCommandListener(this);
            try {
                  local = LocalDevice.getLocalDevice();
                  // Servers set the discoverable mode to GIAC
                  local.setDiscoverable(DiscoveryAgent.GIAC);
            } catch (Exception e) {
            }
            doDeviceDiscovery();
            display.setCurrent(activeDevices);
      }

      public void pauseApp() {
      }

      public void destroyApp(boolean unconditional) {
            notifyDestroyed();
      }

      public void commandAction(Command cmd, Displayable disp) {
            if (cmd == select && disp == activeDevices) {
                  int device = activeDevices.getSelectedIndex();
                  doServiceSearch((RemoteDevice) devicesFound.elementAt(device));
                  
                  int service = activeServices.getSelectedIndex();
                  connectionURL = servicesFound[service].getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
                  try {
                        StreamConnection connection = (StreamConnection) Connector.open(connectionURL);
                        
                        Alert alert1 = new Alert("incoming Data");
                        DataInputStream dataIn = connection.openDataInputStream();
                  	  	String lineRead = dataIn.readUTF();
                  	  	alert1.setString(lineRead);
                        display.setCurrent(alert1);
                        
                        OutputStream outStream = connection.openOutputStream();
                        PrintStream pWriter=new PrintStream(outStream);
                        pWriter.print("Response String from SPP Server\r\n");
                        pWriter.flush();
                        pWriter.close();
                  } catch (Exception e) {
                        Alert alert = new Alert("erro");
                        alert.setString(e.toString());
                        display.setCurrent(alert);
                  }
                  display.setCurrent(activeServices);
                  //doServiceSearch( (RemoteDevice)devicesFound.firstElement());
            }
            //  client connection for a service
            if (cmd == select && disp == activeServices) {
                  int service = activeServices.getSelectedIndex();
                  connectionURL = servicesFound[service].getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
                  try {
                        StreamConnection connection = (StreamConnection) Connector.open(connectionURL);
                        
                        Alert alert1 = new Alert("incoming Data");
                        DataInputStream dataIn = connection.openDataInputStream();
                  	  	String lineRead = dataIn.readUTF();
                  	  	alert1.setString(lineRead);
                        display.setCurrent(alert1);
                        
                        OutputStream outStream = connection.openOutputStream();
                        PrintStream pWriter=new PrintStream(outStream);
                        pWriter.print("Response String from SPP Server\r\n");
                        pWriter.flush();
                        pWriter.close();
                  } catch (Exception e) {
                        Alert alert = new Alert("erro");
                        alert.setString(e.toString());
                        display.setCurrent(alert);
                  }
            }
            if (cmd == exit) {
                  destroyApp(false);
            }
      }
      
      public void inquiryCompleted(int param) {
            switch (param) {
                  case DiscoveryListener.INQUIRY_COMPLETED:
                        /* Inquiry completed normally, add appropriate code
                         * here
                         */
                        if (devicesFound.size() > 0) {
                              activeDevices.addCommand(select);
                              activeDevices.setSelectCommand(select);
                              try {
                                  startServer();
                            } catch (Exception e) {   }
                        } else {
                              try {
                                    activeDevices.append("No Devices Found", null);
                                    startServer();
                              } catch (Exception e) {
                              }
                        }
                        break;

                  case DiscoveryListener.INQUIRY_ERROR:
                        // Error during inquiry, add appropriate code here.
                        break;

                  case DiscoveryListener.INQUIRY_TERMINATED:
                        /* Inquiry terminated by agent.cancelInquiry()
                        * Add appropriate code here.
                        */
                        break;
            }
      }

      public void serviceSearchCompleted(int transID, int respCode) {
            switch (respCode) {
                  case DiscoveryListener.SERVICE_SEARCH_COMPLETED:
                        break;
                  case DiscoveryListener.SERVICE_SEARCH_DEVICE_NOT_REACHABLE:
                        break;
                  case DiscoveryListener.SERVICE_SEARCH_ERROR:
                        break;
                  case DiscoveryListener.SERVICE_SEARCH_NO_RECORDS:
                        break;
                  case DiscoveryListener.SERVICE_SEARCH_TERMINATED:
                        break;
            }
      }

      public void servicesDiscovered(int transID, ServiceRecord[] serviceRecord) {
            servicesFound = serviceRecord;
            activeServices.append(servicesFound.toString(), null);
            activeServices.addCommand(select);
            activeServices.setSelectCommand(select);
      }

      public void deviceDiscovered(RemoteDevice remoteDevice, DeviceClass deviceClass) {
            String str = null;
            try {
                  str = remoteDevice.getFriendlyName(true);
            } catch (Exception e) {
            }
            activeDevices.append(str, null);
            devicesFound.addElement(remoteDevice);
      }

      private void doDeviceDiscovery() {
            agent = local.getDiscoveryAgent();
            devicesFound = new Vector();
            try {
                  if (!agent.startInquiry(DiscoveryAgent.GIAC, this)) {
                	  Alert alert1 = new Alert("inInquiry");
                      alert1.setString("trying inquiry");
                      display.setCurrent(alert1);
                  }
            } catch (BluetoothStateException bse) {
            	Alert alert1 = new Alert("InqEx");
                alert1.setString("InqEx"+ " "+ bse.toString());
                display.setCurrent(alert1);
            }
      }

      private void doServiceSearch(RemoteDevice device) {
            int[] attributes = {0x100, 0x101, 0x102};
            UUID[] uuids = new UUID[1];
            uuids[0] = new UUID("16aa89602c434d3a93032c5f570831eb", false);
            try {
                  agent.searchServices(attributes, uuids, device, this);
            } catch (BluetoothStateException e) {
                  Alert alert1 = new Alert("Error");
                  alert1.setString(e.toString());
                  display.setCurrent(alert1);
            }
            try {
                int transID = agent.searchServices(
                		attributes, uuids, device, this);
                // Display progress message
                System.out.println(
                    "Service Search in Progress ("+transID+")");
                synchronized (serviceSearchSemaphore) {
                    serviceSearchSemaphore.wait();
                }
            } catch (InterruptedException ie) {
                // Ignore
            } catch (BluetoothStateException bse) {
                // ...
                System.out.println("Service Search Failed");
                return;
            }

      }

      public void startServer() throws IOException {
    	  	Alert alert1 = new Alert("Device");
            UUID uuid = new UUID("16aa89602c434d3a93032c5f570831eb", false); // used "uuidgen -t" command in cygwin to generate UUID
            final UUID[] uuids = {uuid};

            //Create the service url
            String connectionString = "btspp://localhost:" + uuid.toString() + ";name=ECGMonitoring";
            //open server url
            StreamConnectionNotifier streamConnNotifier = (StreamConnectionNotifier) Connector.open(connectionString);
            
            //Wait for client connection
            alert1.setString("\nServer Started. Waiting for clients to connect...");
            display.setCurrent(alert1);
            System.out.println("\nServer Started. Waiting for clients to connect...");
            
         // Insert service record into SDDB and wait for an incoming client
            StreamConnection connection = streamConnNotifier.acceptAndOpen();
         // New client connection accepted; get a handle on it
            RemoteDevice dev = RemoteDevice.getRemoteDevice(connection);
            
            alert1.setString("Remote device address: " + dev.getBluetoothAddress() + "\nRemote device name: " + dev.getFriendlyName(true));
            display.setCurrent(alert1);
            System.out.println("Remote device address: " + dev.getBluetoothAddress());
            System.out.println("Remote device name: " + dev.getFriendlyName(true));

            //read string from spp client
            try {
            	// Read input message, in this example a String
            	  DataInputStream dataIn = connection.openDataInputStream();
            	  String lineRead = dataIn.readUTF();

                  //DataInputStream in = (DataInputStream) connection.openDataInputStream();
                  //InputStreamReader bReader= new InputStreamReader(in);
                  //String lineRead=bReader.toString();
            	  alert1.setString(lineRead);
                  display.setCurrent(alert1);
                  System.out.println(lineRead);
                  /*//send response to spp client
                  OutputStream outStream=connection.openOutputStream();
                  PrintWriter pWriter=new PrintWriter(new OutputStreamWriter(outStream));
                  pWriter.write("Response String from SPP Server\r\n");
                  pWriter.flush();
                  pWriter.close();*/
                  streamConnNotifier.close();
            }
            catch(Exception ex){}
      } 
}




