Ejemplo n.º 1
0
    /**
     * Generates an SSL-enabled socket.
     *
     * @return the new socket
     * @throws GeneralSecurityException on error building the socket
     * @throws IOException on error loading the KeyStore
     */
    private SSLSocket getSslSocket(RemoteDevice target)
        throws GeneralSecurityException, IOException {
      // Build a new key store based on the key store manager.
      KeyManager[] keyManagers = coreService.getKeyStoreManager().getKeyManagers();
      TrustManager[] trustManagers = coreService.getKeyStoreManager().getTrustManagers();

      if (keyManagers.length == 0) {
        throw new IllegalStateException("No key managers");
      }

      // Create a new SSLContext, using the new KeyManagers and TrustManagers
      // as the sources of keys and trust decisions, respectively.
      SSLContext sslContext = SSLContext.getInstance("TLS");
      sslContext.init(keyManagers, trustManagers, null);

      // Finally, build a new SSLSocketFactory from the SSLContext, and
      // then generate a new SSLSocket from it.
      SSLSocketFactory factory = sslContext.getSocketFactory();
      SSLSocket sock = (SSLSocket) factory.createSocket();
      sock.setNeedClientAuth(true);
      sock.setUseClientMode(true);
      sock.setKeepAlive(true);
      sock.setTcpNoDelay(true);

      InetSocketAddress fullAddr = new InetSocketAddress(target.getAddress(), target.getPort());
      sock.connect(fullAddr, SOCKET_CREATION_TIMEOUT_MS);
      sock.startHandshake();

      return sock;
    }
Ejemplo n.º 2
0
 private void setNameForDeviceWithBDAddr(String remoteName, BD_ADDR bdAddr) {
   RemoteDevice device = deviceForBDAddr(bdAddr);
   if (device != null) {
     addMessage("Found " + remoteName);
     device.setName(remoteName);
   }
 }
Ejemplo n.º 3
0
 private boolean hasMoreRemoteNameRequests() {
   for (RemoteDevice device : devices) {
     if (device.nameRequest()) {
       return true;
     }
   }
   return false;
 }
Ejemplo n.º 4
0
 private void doNextRemoteNameRequest() {
   for (RemoteDevice device : devices) {
     if (device.nameRequest()) {
       addMessage("Get remote name of " + device.getBDAddress());
       device.inquireName(btstack);
       return;
     }
   }
 }
Ejemplo n.º 5
0
  /** Loads an existing configuration, and builds the socket to the target. */
  private void loadConfig() {
    SharedPreferences pref = getSharedPreferences(SHARED_PREF_NAME, MODE_PRIVATE);

    RemoteDevice restoredTarget = loadRemoteDevice(pref, "");

    for (int i = 0; i < getResources().getInteger(R.integer.recently_connected_count); ++i) {
      RemoteDevice remoteDevice = loadRemoteDevice(pref, "_" + i);
      if (remoteDevice != null) {
        recentlyConnected.put(remoteDevice.getAddress(), remoteDevice);
      }
    }

    if (restoredTarget != null) {
      setTarget(restoredTarget);
    }
  }
Ejemplo n.º 6
0
  /**
   * The listen method for the servicing new peers.
   *
   * @throws IOException In case an unexpected error happens while reading connections
   */
  public void listen() throws IOException {
    int id = 0;
    ServerSocket listenSocket = new ServerSocket(serverPort);
    while (true) {
      Socket clientSocket = listenSocket.accept();
      clientSocket.setSoTimeout(5000);
      DataInputStream in = new DataInputStream(clientSocket.getInputStream());
      DataOutputStream out = new DataOutputStream(clientSocket.getOutputStream());

      try {
        String ipAddress = clientSocket.getInetAddress().getHostAddress();

        /* Ask peer which port will it use for the P2P communication */
        int assignedPort = in.readInt();
        /* Assign an id to peer, send it and close connection */
        id++;
        out.writeInt(id);
        RemoteDevice newClient = new RemoteDevice(id, ipAddress, assignedPort);

        /* Send the peer list */
        ArrayList<RemoteDevice> peersCopy = new ArrayList<RemoteDevice>(peers);
        for (RemoteDevice peer : peersCopy) {
          out.writeBoolean(true);
          out.writeInt(peer.getId());
          out.writeUTF(peer.getIpAddress());
          out.writeInt(peer.getPort());
        }
        out.writeBoolean(false);

        /* Add new peer to peer list */
        getPeers().add(newClient);
      } catch (SocketTimeoutException ste) {
        System.err.println(
            "Socket timeout from peer: " + clientSocket.getInetAddress().getHostAddress());
      } catch (IOException ioe) {
        System.err.println(
            "IOE exception while initializing peer: "
                + clientSocket.getInetAddress().getHostAddress());
      } finally {
        clientSocket.close();
      }
    }
  }
Ejemplo n.º 7
0
  /**
   * Pings a peer to test if it's still alive, and sends a list of peers that have disconnected.
   *
   * @throws IOException In case an unexpected error happens while reading connections
   */
  public void ping(RemoteDevice peer) throws IOException {

    try {
      Socket peerSocket = new Socket();
      peerSocket.connect(new InetSocketAddress(peer.getIpAddress(), peer.getPort()), 5000);

      DataInputStream in = new DataInputStream(peerSocket.getInputStream());
      DataOutputStream out = new DataOutputStream(peerSocket.getOutputStream());

      /* The tracker will use the special ID -2 */
      out.writeInt(-2);
      out.writeInt(serverPort);

      /* We prepare the list of peers that have been disconnected */
      String message = "";
      ArrayList<RemoteDevice> disPeersCopy = new ArrayList<RemoteDevice>(disPeers);
      for (RemoteDevice opeer : disPeersCopy) {
        message += opeer.getId() + "|";
      }
      if (message.length() > 0) {
        message = message.substring(0, message.length() - 1);
      }

      /* We send the reply */
      out.writeInt(0);
      out.writeUTF("ping");
      out.writeUTF("pong" + message);

      /* We clear the notifying list if everyone has been notified */
      notPeers++;
      if (notPeers >= peers.size()) {
        disPeers = new ArrayList<RemoteDevice>();
        notPeers = 0;
      }

      try {
        peerSocket.close();
      } catch (IOException ioe) {
        System.err.println("IOException while closing peer " + ioe.getMessage());
      }
      /* The peer appears to be disconnected, remove it from the peerlist */
    } catch (SocketTimeoutException ste) {
      System.out.println("Peer " + peer.getId() + " is no longer responding.");
      peers.remove(peer);
      disPeers.add(peer);
      notPeers = 0;
    } catch (UnknownHostException uhe) {
      System.err.println("Unknown host: " + peer.getIpAddress());
    } catch (IOException ioe) {
      System.out.println("Peer " + peer.getId() + " is no longer responding.");
      peers.remove(peer);
      disPeers.add(peer);
      notPeers = 0;
    }
  }
Ejemplo n.º 8
0
 private RemoteDevice deviceForBDAddr(BD_ADDR bdAddr) {
   for (RemoteDevice device : devices) {
     if (device.getBDAddress().equals(bdAddr)) return device;
   }
   return null;
 }
Ejemplo n.º 9
0
  @SuppressLint("DefaultLocale")
  public void handlePacket(Packet packet) {
    if (packet instanceof HCIEventHardwareError) {
      clearMessages();
      addMessage(
          "Received HCIEventHardwareError, \nhandle power cycle of the Bluetooth \nchip of the device.");
    }

    if (packet instanceof HCIEventDisconnectionComplete) {
      HCIEventDisconnectionComplete event = (HCIEventDisconnectionComplete) packet;
      testHandle = event.getConnectionHandle();
      addMessage(
          String.format(
              "Received disconnect, status %d, handle %x", event.getStatus(), testHandle));
      restartInquiry();
      return;
    }

    switch (state) {
      case w4_btstack_working:
        if (packet instanceof BTstackEventState) {
          BTstackEventState event = (BTstackEventState) packet;
          if (event.getState() == 2) {
            addMessage("BTstack working. Set write inquiry mode.");
            state = STATE.w4_write_inquiry_mode;
            btstack.HCIWriteInquiryMode(1); // with RSSI
          }
        }
        break;

      case w4_write_inquiry_mode:
        if (packet instanceof HCIEventCommandComplete) {
          state = STATE.w4_scan_result;
          btstack.HCIInquiry(HCI_INQUIRY_LAP, INQUIRY_INTERVAL, 0);
        }
        break;

      case w4_scan_result:
        if (packet instanceof HCIEventInquiryResultWithRssi) {
          HCIEventInquiryResultWithRssi result = (HCIEventInquiryResultWithRssi) packet;
          devices.add(
              new RemoteDevice(
                  result.getBdAddr(), result.getPageScanRepetitionMode(), result.getClockOffset()));
          addMessage("Found device: " + result.getBdAddr());
        }

        if (packet instanceof HCIEventInquiryComplete) {
          state = STATE.w4_remote_name;
          if (hasMoreRemoteNameRequests()) {
            doNextRemoteNameRequest();
            break;
          }
        }
        break;

      case w4_remote_name:
        if (packet instanceof HCIEventRemoteNameRequestComplete) {
          HCIEventRemoteNameRequestComplete result = (HCIEventRemoteNameRequestComplete) packet;
          if (result.getStatus() == 0) {
            // store name on success
            setNameForDeviceWithBDAddr(result.getRemoteName(), result.getBdAddr());
          }

          if (hasMoreRemoteNameRequests()) {
            doNextRemoteNameRequest();
            break;
          }

          // discovery done, connect to device with remote name prefix

          RemoteDevice remoteDevice = null;
          for (RemoteDevice device : devices) {
            if (device.getName() != null
                && device.getName().startsWith(REMOTE_DEVICE_NAME_PREFIX)) {
              remoteDevice = device;
            }
          }

          // try first one otherwise
          if (remoteDevice == null && devices.size() > 0) {
            remoteDevice = devices.get(0);
          }

          // no device, restart inquiry
          if (remoteDevice == null) {
            restartInquiry();
            break;
          }

          // start SDP query for RFCOMMM services
          remoteBDAddr = remoteDevice.getBDAddress();
          if (remoteDevice.getName() == null) {
            addMessage("Start SDP Query of " + remoteDevice.getBDAddress());
          } else {
            addMessage("Start SDP Query of " + remoteDevice.getName());
          }
          state = STATE.w4_sdp_query_result;
          byte[] serviceSearchPattern = Util.serviceSearchPatternForUUID16(SPP_UUID);
          btstack.SDPClientQueryRFCOMMServices(remoteBDAddr, serviceSearchPattern);
          break;
        }
        break;

      case w4_sdp_query_result:
        if (packet instanceof SDPQueryRFCOMMService) {
          SDPQueryRFCOMMService service = (SDPQueryRFCOMMService) packet;
          services.add(service);
          addMessage(
              String.format(
                  "Found \"%s\", channel %d", service.getName(), service.getRFCOMMChannel()));
        }
        if (packet instanceof SDPQueryComplete) {
          // find service with "SPP" prefix
          SDPQueryRFCOMMService selectedService = null;
          for (SDPQueryRFCOMMService service : services) {
            if (service.getName().startsWith(RFCOMM_SERVICE_PREFIX)) {
              selectedService = service;
              break;
            }
          }
          // restart demo, if no service with prefix found
          if (selectedService == null) {
            restartInquiry();
            break;
          }

          // connect
          state = STATE.w4_connected;
          clearMessages();
          addMessage("SPP Test Application / Part 2");
          addMessage("Connect to channel nr " + selectedService.getRFCOMMChannel());
          btstack.RFCOMMCreateChannel(remoteBDAddr, selectedService.getRFCOMMChannel());
        }

        break;

      case w4_connected:
        if (packet instanceof RFCOMMEventOpenChannelComplete) {
          RFCOMMEventOpenChannelComplete e = (RFCOMMEventOpenChannelComplete) packet;
          if (e.getStatus() != 0) {
            addMessage("RFCOMM channel open failed, status " + e.getStatus());
          } else {
            state = STATE.active;
            rfcommChannelID = e.getRFCOMMCid();
            mtu = e.getMaxFrameSize();
            addMessage(
                String.format(
                    "RFCOMM channel open succeeded. \nNew RFCOMM Channel ID %d,\n max frame size %d",
                    rfcommChannelID, mtu));

            counter = 0;
            new Thread(
                    new Runnable() {
                      @Override
                      public void run() {
                        try {
                          while (state == STATE.active) {
                            Thread.sleep(1000);
                            byte[] data;
                            try {
                              data =
                                  String.format("BTstack SPP Counter %d\n", counter)
                                      .getBytes("utf8");
                              if (counter < Integer.MAX_VALUE) {
                                counter++;
                              } else {
                                counter = 0;
                              }
                              btstack.RFCOMMSendData(rfcommChannelID, data);
                            } catch (UnsupportedEncodingException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                            }
                          }
                        } catch (InterruptedException e) {
                        }
                      }
                    })
                .start();
          }
        }
        break;

      case active:
        if (packet instanceof RFCOMMDataPacket) {
          addTempMessage("Received RFCOMM data packet: \n" + packet.toString());
        }
        break;

      default:
        break;
    }
  }
Ejemplo n.º 10
0
 private void addRecentlyConnected(RemoteDevice remoteDevice) {
   recentlyConnected.remove(remoteDevice.getAddress());
   recentlyConnected.put(remoteDevice.getAddress(), remoteDevice);
   storeConfig();
 }
Ejemplo n.º 11
0
 private void storeRemoteDevice(
     SharedPreferences.Editor prefEdit, String suffix, RemoteDevice remoteDevice) {
   prefEdit.putString(DEVICE_NAME_TAG + suffix, remoteDevice.getName());
   prefEdit.putString(DEVICE_IP_TAG + suffix, remoteDevice.getAddress().getHostAddress());
   prefEdit.putInt(DEVICE_PORT_TAG + suffix, remoteDevice.getPort());
 }