Android Open Source - mha-android Discovery Search






From Project

Back to project page mha-android.

License

The source code is released under:

Copyright (c) 2011-2012 Cameron Porter, Ryan Brown http://github.com/camporter/mha-android Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated...

If you think the Android project mha-android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.teamacra.myhomeaudio.discovery;
//  w  w  w . j a  v a2  s  .c o  m
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.util.StringTokenizer;
import android.net.DhcpInfo;

public final class DiscoverySearch {

  protected InetAddress broadcastAddress;
  protected int broadcastPort;

  protected String serviceName;
  protected boolean shouldRun = true;
  protected DatagramSocket socket;
  protected DatagramPacket queuedPacket;
  protected DatagramPacket receivedPacket;

  protected DhcpInfo dhcp;

  public DiscoverySearch(String serviceName, DhcpInfo dhcp) {

    this.dhcp = dhcp;
    this.serviceName = serviceName;

    broadcastPort = DiscoveryConstants.SEARCH_BROADCAST_PORT;
    try {
      broadcastAddress = getBroadcastAddress();
    } catch (UnknownHostException e1) {
      e1.printStackTrace();
      System.exit(1);
    }
    if (broadcastAddress == null)
      System.exit(1);

    try {
      this.socket = new DatagramSocket(broadcastPort);
      this.socket.setBroadcast(true);
      this.socket.setSoTimeout(DiscoveryConstants.SEARCH_SOCKET_TIMEOUT);

    } catch (SocketException e) {
      e.printStackTrace();
      System.exit(1);
    }
  }

  public String getServiceName() {
    return serviceName;
  }

  protected String getEncodedServiceName() {
    try {
      return URLEncoder.encode(getServiceName(), "UTF-8");
    } catch (UnsupportedEncodingException uee) {
      return null;
    }
  }

  public void setServiceName(String serviceName) {
    this.serviceName = serviceName;
  }

  /**
   * Starts the actual discovery process.
   * 
   * @return The ip address we get back for the discovered server.
   */
  public String run() {
    int i = 0;
    while (i < 3) {
      DatagramPacket packet = getQueryPacket();
      if (packet != null) {
        queuedPacket = packet;
      }
      sendQueuedPacket();

      try {
        // Wait 800 msecs, latency should be much lower than this on
        // nearly
        // all networks.
        Thread.sleep(800);
      } catch (InterruptedException e) {
        e.printStackTrace();
        return null;
      }
      int j = 0;
      while (j < 2) {
        try {
          byte[] buf = new byte[DiscoveryConstants.DATAGRAM_LENGTH];
          receivedPacket = new DatagramPacket(buf, buf.length);
          socket.receive(receivedPacket); // This will timeout
                          // thankfully
          if (isReplyPacket()) {
            DiscoveryDescription descriptor = null;
            descriptor = getReplyDescriptor();
            if (descriptor != null) {
              // notifyReply(descriptor);
              return receivedPacket.getAddress().getHostAddress();
              // return descriptor;
            }
          }
        } catch (SocketTimeoutException ste) {
        } catch (IOException ioe) {
          ioe.printStackTrace();
        }
        j++;
      }
      i++;
    }

    return null;

  }

  /**
   * Closes the socket and does other cleanup.
   */
  public void end() {
    socket.close();
  }

  protected void sendQueuedPacket() {
    if (queuedPacket == null) {
      return;
    }
    try {
      socket.send(queuedPacket);
      queuedPacket = null;
    } catch (IOException ioe) {
      ioe.printStackTrace();
    }
  }

  /**
   * Figures out if the packet we get back is valid as a reply.
   * 
   * @return Whether or not it is a valid reply.
   */
  protected boolean isReplyPacket() {
    if (receivedPacket == null) {
      return false;
    }

    String dataStr = new String(receivedPacket.getData());
    int pos = dataStr.indexOf((char) 0);
    if (pos > -1) {
      dataStr = dataStr.substring(0, pos);
    }

    if (dataStr.startsWith(DiscoveryConstants.REPLY_HEADER
        + getEncodedServiceName())) {
      return true;
    }

    return false;
  }

  /**
   * Builds a DiscoveryDescription from the packet that we receive.
   * 
   * @return The generated DiscoveryDescriptor if the packet is formatted
   *         correctly, or null otherwise.
   */
  protected DiscoveryDescription getReplyDescriptor() {
    String dataStr = new String(receivedPacket.getData());
    int pos = dataStr.indexOf((char) 0);
    if (pos > -1) {
      dataStr = dataStr.substring(0, pos);
    }

    StringTokenizer tokens = new StringTokenizer(
        dataStr.substring(15 + getEncodedServiceName().length()));
    if (tokens.countTokens() == 4) {
      return DiscoveryDescription.parse(tokens.nextToken(), tokens.nextToken(),
          tokens.nextToken(), tokens.nextToken());
    } else {
      return null;
    }
  }

  /**
   * Builds a DatagramPacket with the information we need to find a server.
   * 
   * @return DatagramPacket assigned with the correct address, port, and data.
   */
  protected DatagramPacket getQueryPacket() {
    StringBuffer buf = new StringBuffer();
    buf.append(DiscoveryConstants.SEARCH_HEADER + getEncodedServiceName());

    byte[] bytes = buf.toString().getBytes();
    DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
    packet.setAddress(broadcastAddress);
    packet.setPort(DiscoveryConstants.RESPONDER_BROADCAST_PORT);

    return packet;
  }

  /**
   * Figures out the local broadcast address for the network that the device
   * is connected to, using DHCP information.
   * 
   * @return The InetAddress associated to the broadcast ip.
   * @throws UnknownHostException
   */
  protected InetAddress getBroadcastAddress() throws UnknownHostException {
    int broadcast = (dhcp.ipAddress & dhcp.netmask) | ~dhcp.netmask;
    byte[] quads = new byte[4];
    for (int i = 0; i < 4; i++)
      quads[i] = (byte) ((broadcast >> i * 8) & 0xFF);
    return InetAddress.getByAddress(quads);
  }
}




Java Source Code List

com.teamacra.myhomeaudio.MHAApplication.java
com.teamacra.myhomeaudio.bluetooth.BluetoothService.java
com.teamacra.myhomeaudio.discovery.DiscoveryConstants.java
com.teamacra.myhomeaudio.discovery.DiscoveryDescription.java
com.teamacra.myhomeaudio.discovery.DiscoverySearchListener.java
com.teamacra.myhomeaudio.discovery.DiscoverySearch.java
com.teamacra.myhomeaudio.discovery.MDNSDiscovery.java
com.teamacra.myhomeaudio.http.HttpBase.java
com.teamacra.myhomeaudio.http.HttpClient.java
com.teamacra.myhomeaudio.http.HttpNode.java
com.teamacra.myhomeaudio.http.HttpSource.java
com.teamacra.myhomeaudio.http.HttpStream.java
com.teamacra.myhomeaudio.http.StatusCode.java
com.teamacra.myhomeaudio.locations.NodeSignalRange.java
com.teamacra.myhomeaudio.locations.NodeSignature.java
com.teamacra.myhomeaudio.manager.ConfigurationManager.java
com.teamacra.myhomeaudio.manager.LocationManager.java
com.teamacra.myhomeaudio.manager.NodeManager.java
com.teamacra.myhomeaudio.manager.StreamManager.java
com.teamacra.myhomeaudio.media.MediaDescriptor.java
com.teamacra.myhomeaudio.node.Node.java
com.teamacra.myhomeaudio.source.Source.java
com.teamacra.myhomeaudio.stream.StreamAction.java
com.teamacra.myhomeaudio.stream.Stream.java
com.teamacra.myhomeaudio.ui.InitialConfigActivity.java
com.teamacra.myhomeaudio.ui.LoginActivity.java
com.teamacra.myhomeaudio.ui.MyHomeAudioActivity.java
com.teamacra.myhomeaudio.ui.RegisterActivity.java
com.teamacra.myhomeaudio.ui.fragment.SongFragment.java
com.teamacra.myhomeaudio.ui.fragment.SourceFragment.java
com.teamacra.myhomeaudio.ui.fragment.TestFragment.java