title: Linux Bluetooth not finding Android Service with UUID
body: <p>I am trying to write a program on an embedded system running GUMSTIX(Linux) to connect and talk to an Android 2.x device over bluetooth.  The GUMSTIX is the client and the Android is the server.  I am trying to find the channel number that my Android service uses so that the GUMSTIX can connect to it but for some reason my routine isn't returning a channel number because it doesn't seem to find a service with a matching UUID.</p>
  
  <p>I suspect that the UUID provided to the GUMSTIX routine and the UUID on the Android device are not actually the same number.  Android requires a 128 bit UUID :</p>
  
  <p>From the <a href="http://developer.android.com/reference/java/util/UUID.htmldetails." rel="nofollow">Android Documentation</a>:</p>
  
  <blockquote>
    <p>UUID is an immutable representation of
    a 128-bit universally unique
    identifier (UUID).</p>
    
    <p>There are multiple, variant layouts of
    UUIDs, but this class is based upon
    variant 2 of RFC 4122, the Leach-Salz
    variant. This class can be used to
    model alternate variants, but most of
    the methods will be unsupported in
    those cases; see each method for</p>
  </blockquote>
  
  <p>UUID used in android:</p>
  
  <pre><code>public static final String UUID_STRING = "00000000-0000-0000-0000-00000000ABCD";
  private static final UUID MY_UUID = UUID.fromString(UUID_STRING);
  </code></pre>
  
  <p>C Code in GUMSTIX <strong>Look for comment indicating where it fails</strong></p>
  
  <pre><code>int main(int argc , char **argv)
  {
  //Android wants a 128 bit UUID why are we only giving a 32 bit UUID
  uint32_t svc_uuid_int[] = { 0 , 0 , 0 , 0xABCD } ;
  
  int status ;
  bdaddr_t target ;
  uuid_t svc_uuid ;
  sdp_list_t *response_list , *search_list , *attrid_list ;
  sdp_session_t *session = 0;
  uint32_t range = 0x0000ffff ;
  uint8_t port = 0;
  
  if(argc &lt; 2)
  {
      fprintf(stderr , "usage: %s &lt;bt_addr&gt;\n" , argv [ 0 ] ) ;
      exit ( 2 ) ;
  }
  
  str2ba ( argv[1] , &amp;target ) ;
  // connect to the SDP server running on the remote machine
  session = sdp_connect ( BDADDR_ANY, &amp;target, SDP_RETRY_IF_BUSY  );
  //  printf("session %u\n",session);
  
  sdp_uuid128_create( &amp;svc_uuid, &amp;svc_uuid_int ) ;
  search_list = sdp_list_append( 0, &amp;svc_uuid ) ;
  attrid_list = sdp_list_append( 0, &amp;range ) ;
  
  // get a list of service records that have UUID 0xabcd
  response_list = NULL ;   //ERROR: response_list SHOULD GET INITIALIZED BUT IT STAYS NULL CAUSING THE PROGRAM TO NEVER ENTER THE FOR LOOP BELOW.
  status = sdp_service_search_attr_req(session , search_list , SDP_ATTR_REQ_RANGE , attrid_list, &amp;response_list ) ;
  printf("status %d\n",status);
  
  if( status == 0 )
  {
      sdp_list_t *proto_list = NULL ;
      sdp_list_t *r = response_list ;
      // go through each of the service records
      for ( ; r ; r = r-&gt;next )
      {
          sdp_record_t *rec = (sdp_record_t * ) r-&gt;data ;
          // get a list of the protocol sequences
          if( sdp_get_access_protos( rec, &amp;proto_list ) == 0 ) 
          {
              // get the RFCOMM port number
              port = sdp_get_proto_port( proto_list , RFCOMM_UUID ) ;
              sdp_list_free( proto_list, 0 );
          }
          sdp_record_free( rec ) ;
      }
  }
  
  sdp_list_free( response_list, 0 );
  sdp_list_free( search_list, 0 );
  sdp_list_free( attrid_list, 0 );
  sdp_close( session ) ;
  if( port != 0 )
  {
      printf( "found service running on RFCOMM port %d\n" , port ) ;
  }
  return 0;
  </code></pre>
  
  <p>}</p>
  
  <p>EDIT:</p>
  
  <p>Android code for the acceptThread(accepts connections), ConnectThread(completes the connection), and ConnectedThread(maintains the connection, establish handler)</p>
  
  <pre><code>/**
   * This thread runs while listening for incoming connections. It behaves
   * like a server-side client. It runs until a connection is accepted
   * (or until canceled).
   */
  private class AcceptThread extends Thread {
      // The local server socket
      private final BluetoothServerSocket mmServerSocket;
  
      public AcceptThread() {
          BluetoothServerSocket tmp = null;
  
          // Create a new listening server socket
          try {
              tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
          } catch (IOException e) {
              Log.e(TAG, "listen() failed", e);
          }
          mmServerSocket = tmp;
      }
  
      public void run() {
          if (D) Log.d(TAG, "BEGIN mAcceptThread" + this);
          setName("AcceptThread");
          BluetoothSocket socket = null;
  
          // Listen to the server socket if we're not connected
          while (mState != STATE_CONNECTED) {
              try {
                  // This is a blocking call and will only return on a
                  // successful connection or an exception
                  if(D) Log.i("prism", "Waiting to connect************");
                  socket = mmServerSocket.accept();
                  if(D) Log.i("prism", "We have accepted connection and are connected***************");
              } catch (IOException e) {
                  Log.e(TAG, "accept() failed", e);
                  break;
              }
  
              // If a connection was accepted
              if (socket != null) {
                  synchronized (BluetoothServer.this) {
                      switch (mState) {
                      case STATE_LISTEN:
                      case STATE_CONNECTING:
                          // Situation normal. Start the connected thread.
                          connected(socket, socket.getRemoteDevice());
                          break;
                      case STATE_NONE:
                      case STATE_CONNECTED:
                          // Either not ready or already connected. Terminate new socket.
                          try {
                              if (D) Log.i("prism", "Bluetooth already connected, abandoning request from " + socket.getRemoteDevice().getName());
                              socket.close();
                          } catch (IOException e) {
                              Log.e(TAG, "Could not close unwanted socket", e);
                          }
                          break;
                      }
                  }
              }
          }
          if (D) Log.i(TAG, "END mAcceptThread");
      }
  
      public void cancel() {
          if (D) Log.d(TAG, "cancel " + this);
          try {
              mmServerSocket.close();
          } catch (IOException e) {
              Log.e(TAG, "close() of server failed", e);
          }
      }
  }
  
  /**
   * This thread runs while attempting to make an outgoing connection
   * with a device. It runs straight through; the connection either
   * succeeds or fails.
   */
  private class ConnectThread extends Thread {
      private final BluetoothSocket mmSocket;
      private final BluetoothDevice mmDevice;
  
      public ConnectThread(BluetoothDevice device) {
          mmDevice = device;
          BluetoothSocket tmp = null;
  
          // Get a BluetoothSocket for a connection with the
          // given BluetoothDevice
          try {
              tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
          } catch (IOException e) {
              Log.e(TAG, "create() failed", e);
          }
          mmSocket = tmp;
      }
  
      public void run() {
          Log.i(TAG, "BEGIN mConnectThread");
          setName("ConnectThread");
  
          // Always cancel discovery because it will slow down a connection
          mAdapter.cancelDiscovery();
  
          // Make a connection to the BluetoothSocket
          try {
              // This is a blocking call and will only return on a
              // successful connection or an exception
              Log.i(TAG, "mmSocket.connect() is initiaiting in the ConnectThread");
              mmSocket.connect();
              Log.i(TAG, "mmSocket.connect() complete...");
          } catch (IOException e) {
              Log.e(TAG, "Connection attempt failed, closing the socket");
              connectionFailed();
              // Close the socket
              try {
                  mmSocket.close();
              } catch (IOException e2) {
                  Log.e(TAG, "unable to close() socket during connection failure", e2);
              }
              // Start the service over to restart listening mode
              BluetoothServer.this.start();
              return;
          }
  
          // Reset the ConnectThread because we're done
          synchronized (BluetoothServer.this) {
              mConnectThread = null;
          }
  
          // Start the connected thread
          connected(mmSocket, mmDevice);
      }
  
      public void cancel() {
          try {
              mmSocket.close();
          } catch (IOException e) {
              Log.e(TAG, "close() of connect socket failed", e);
          }
      }
  }
  
  /**
   * This thread runs during a connection with a remote device.
   * It handles all incoming and outgoing transmissions.
   */
  private class ConnectedThread extends Thread {
      private final BluetoothSocket mmSocket;
      private final InputStream mmInStream;
      private final OutputStream mmOutStream;
  
      public ConnectedThread(BluetoothSocket socket) {
          Log.d(TAG, "create ConnectedThread");
          mmSocket = socket;
          InputStream tmpIn = null;
          OutputStream tmpOut = null;
  
          // Get the BluetoothSocket input and output streams
          try {
              tmpIn = socket.getInputStream();
              tmpOut = socket.getOutputStream();
          } catch (IOException e) {
              Log.e(TAG, "temp sockets not created", e);
          }
  
          mmInStream = tmpIn;
          mmOutStream = tmpOut;
      }
  
      public void run() {
          Log.i(TAG, "BEGIN mConnectedThread");
          byte[] buffer = new byte[1024];
          int bytes;
  
          // Keep listening to the InputStream while connected
          while (true) {
              try {
                  // Read from the InputStream
                  bytes = mmInStream.read(buffer);
  
                  // Send the obtained bytes to the UI Activity
                  mHandler.obtainMessage(Bluetooth.MESSAGE_READ, bytes, -1, buffer)
                          .sendToTarget();
              } catch (IOException e) {
                  Log.e(TAG, "disconnected", e);
                  connectionLost();
                  break;
              }
          }
      }
  </code></pre>
  
  <p>The Android code was adopted from the Bluetooth Chat example <a href="http://developer.android.com/resources/samples/BluetoothChat/index.html" rel="nofollow">here</a></p>