implementing FindMe profile in ICS

1k Views Asked by At

I am working on Bluetooth application in android. I am writing an FindMe Server application on ICS. we have incorporated Gatt method in ICS as we are working on Low energy. I am not having FindMe profile API's currently so trying to use GATT method to complete the application. My application is registering to the GATT and it is doing service discovery as well but while doing the service discovery suddenly the bluetooth device is getting disconnected with my phone. can you please tell me what went wrong??

I have copied the code here....All the code is from a single file

public class FindMEService extends Service {

private static final String TAG = "FindMEService";

public static final int MSG_REG_GATT_SERVER_CONFIG = 300;
public static final int MSG_UNREG_GATT_SERVER_CONFIG = 301;

public static final int MSG_REG_GATT_SERVER_SUCCESS = 400;
public static final int MSG_REG_GATT_SERVER_FAILURE = 401;
public static final int MSG_UNREG_GATT_SERVER_SUCCESS = 500;
public static final int MSG_UNREG_GATT_SERVER_FAILURE = 501;

BluetoothGatt gattProfile;
private BluetoothGattAppConfiguration serverConfiguration = null;

InputStream raw = null;

public static ArrayList<Attribute> FMPHandleToAttributes;

public static int serverMinHandle = 0;

public static int serverMaxHandle = -1;

public static HashMap<String, List<Integer>> AttribTypeToHandle =
    new HashMap<String, List<Integer>>();

final Messenger mMessenger = new Messenger(new handler());


@Override
public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    return null;
}

public void onCreate() {
    super.onCreate();
    BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    if(mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
        stopSelf();
        return;
    }

    if (!mBluetoothAdapter.getProfileProxy(this, mBluetoothServiceListener,
            BluetoothProfile.GATT)) {
                stopSelf();
                return;
            }

    populateFMPAttribTypeMap();
    ReadXML readxml= new ReadXML();
            raw = getResources().openRawResource(R.raw.fmpservice);

           if (raw != null) {
              readxml.parse(raw);        
           }

           sendMessage(MSG_REG_GATT_SERVER_CONFIG,0);
       }

public int onStartCommand(Intent intent, int flags, int startId) {
    super.onStartCommand(intent,flags, startId);
    return START_STICKY;
}

public void onDestroy() {
    super.onDestroy();
    sendMessage(MSG_UNREG_GATT_SERVER_CONFIG,0);
}

 private final BluetoothProfile.ServiceListener mBluetoothServiceListener =
     new BluetoothProfile.ServiceListener() {
 public void onServiceConnected(int profile, BluetoothProfile proxy) {
     if (profile == BluetoothProfile.GATT) {
         gattProfile = (BluetoothGatt) proxy;
     }
 }

 public void onServiceDisconnected(int profile) {
     if (profile == BluetoothProfile.GATT) {
         gattProfile = null;
     }
 }
};

private class handler extends Handler {

    public void handleMessage(Message msg) {
        switch(msg.what) {
        case MSG_REG_GATT_SERVER_CONFIG :
            registertoGATT();
            break;
        case MSG_UNREG_GATT_SERVER_CONFIG:
            unregistertoGATT();
            break;
        case MSG_REG_GATT_SERVER_SUCCESS:
                break;
        case MSG_REG_GATT_SERVER_FAILURE:
                break;
        case MSG_UNREG_GATT_SERVER_SUCCESS:
                break;
        case MSG_UNREG_GATT_SERVER_FAILURE:
                break;
        }
    }


}

/**
 * Sending Messages to the Handler
 * @param what
 * @param value
 */
private void sendMessage(int what, int value) {

    if (mMessenger == null) {
        return;
    }

    try {
            mMessenger.send(Message.obtain(null, what, value, 0));
    } catch (RemoteException e) {
        e.printStackTrace();
    }
}

/**
 * Register to GATT
 */
private void registertoGATT() {
         gattProfile.registerServerConfiguration("FMP",0xffff,bluetoothGattCallBack));
}

 private void populateFMPAttribTypeMap() {
        AttribTypeToHandle.put("00002800-0000-1000-8000-00805F9B34FB", new ArrayList<Integer>());
        AttribTypeToHandle.put("00002803-0000-1000-8000-00805F9B34FB", new ArrayList<Integer>());
 }


    /**
     * Callback to handle application registration, unregistration events and other
     * API requests coming from the client device.
    */
    private final BluetoothGattCallback bluetoothGattCallBack = new BluetoothGattCallback() {
        public void onGattAppConfigurationStatusChange(BluetoothGattAppConfiguration config,
                int status) {
            serverConfiguration = config;

            switch(status) {
                case BluetoothGatt.GATT_CONFIG_REGISTRATION_SUCCESS:
                        sendMessage(MSG_REG_GATT_SERVER_SUCCESS, 0);
                        break;
                case BluetoothGatt.GATT_CONFIG_REGISTRATION_FAILURE:
                        sendMessage(MSG_REG_GATT_SERVER_FAILURE, 0);
                        break;
                case BluetoothGatt.GATT_CONFIG_UNREGISTRATION_SUCCESS:
                        sendMessage(MSG_UNREG_GATT_SERVER_SUCCESS, 0);
                        break;
                case BluetoothGatt.GATT_CONFIG_UNREGISTRATION_FAILURE:
                        sendMessage(MSG_UNREG_GATT_SERVER_FAILURE, 0);
                        break;
            }
        }

        public void onGattActionComplete(String action, int status) {
            Log.d(TAG, "FindMEService :  onGattActionComplete: " + action + "Status: " + status);
        }


        /**
         * Processes the Discover Primary Services Request from client and sends the response
         * to the client.
        */
        public void onGattDiscoverPrimaryServiceRequest(BluetoothGattAppConfiguration config,
                        int startHandle, int endHandle, int requestHandle) {
            System.out.println("FindMEService :  onGattDiscoverPrimaryServiceRequest");


        }


        /**
         * Processes the Discover Primary Services by UUID Request from client and sends the
         * response to the client.
        */
        public void onGattDiscoverPrimaryServiceByUuidRequest(BluetoothGattAppConfiguration config,
                        int startHandle, int endHandle, ParcelUuid uuid, int requestHandle) {
             int j, k, hdlFoundStatus =0;
             int startAttrHdl = 0, endAttrHdl = 0;
             int status = BluetoothGatt.ATT_ECODE_ATTR_NOT_FOUND;
             boolean retVal;
             List<Integer> hndlList = null;
             if(AttribTypeToHandle != null) {
                 for(Map.Entry<String, List<Integer>> entry : AttribTypeToHandle.entrySet()) {
                     if("00002800-0000-1000-8000-00805F9B34FB".
                                 equalsIgnoreCase(entry.getKey().toString())) {
                         //List of primary service handles
                         hndlList = entry.getValue();
                     }
                 }
             }
             if(hndlList != null) {
                 for(j=0; j< hndlList.size(); j++) {
                     int handle = hndlList.get(j);
                     if(handle >= 0) {
                         if((handle >= startHandle) && (handle <= endHandle)){
                             if(FMPHandleToAttributes != null) {
                                 for(k=0; k<FMPHandleToAttributes.size(); k++) {
                                     if(handle ==FMPHandleToAttributes.get(k).handle) {
                                         Attribute attr = FMPHandleToAttributes.get(k);
                                         startAttrHdl = attr.startHandle;
                                         endAttrHdl = attr.endHandle;
                                         if(attr.uuid != null &&
                                                         attr.uuid.equalsIgnoreCase(uuid.toString())) {
                                             Log.d(TAG, "Primary Handle with UUID available ::");
                                             hdlFoundStatus = 1;
                                             status = BluetoothGatt.GATT_SUCCESS;
                                             break;
                                         }

                                     }
                                 }
                             }
                         }
                     }
                     if(hdlFoundStatus == 1) {
                         Log.d(TAG, "Primary Handle found, success ::");
                         status = BluetoothGatt.GATT_SUCCESS;
                         break;
                     }
                     if(j == (hndlList.size()-1)) {
                         Log.d(TAG, "Primary Handle not found, failure ::");
                         status = BluetoothGatt.ATT_ECODE_ATTR_NOT_FOUND;
                         break;
                     }
                 }
             }
             retVal = gattProfile.discoverPrimaryServiceByUuidResponse(config, requestHandle, status,
                         startAttrHdl, endAttrHdl, uuid);

        }

        /**
         * Processes the Find Included Services Request from client and sends the response
         * to the client.
        */
        public void onGattFindIncludedServiceRequest(BluetoothGattAppConfiguration config,
                        int startHandle, int endHandle, int requestHandle) {
            System.out.println("FindMEService :  onGattFindIncludedServiceRequest");
        }

        /**
         * Processes the Discover Characteristic Descriptors Request from client and sends the
         * response to the client.
        */
        public void onGattDiscoverCharacteristicDescriptorRequest(BluetoothGattAppConfiguration
                        config, int startHandle, int endHandle, int requestHandle) {
            System.out.println("FindMEService :  onGattDiscoverCharacteristicDescriptorRequest");

        }

        /**
         * Processes the Discover Characteristics Request from client and sends the response
         * to the client.
        */
        public void onGattDiscoverCharacteristicRequest(BluetoothGattAppConfiguration config,
                        int startHandle, int endHandle, int requestHandle) {
            System.out.println("FindMEService :  onGattDiscoverCharacteristicRequest");
              }

        /**
         * Processes the Read By Attribute Type Request from client and sends the response
         * to the client.
        */
        public void onGattReadByTypeRequest(BluetoothGattAppConfiguration config, ParcelUuid uuid,
                int startHandle, int endHandle, String authentication, int requestHandle) {
            System.out.println("FindMEService :  onGattReadByTypeRequest");
        }

        /**
         * Processes the Read Request from client and sends the response
         * to the client.
        */
        public void onGattReadRequest(BluetoothGattAppConfiguration config, int handle,
                        String authentication, int requestHandle) {
            System.out.println("FindMEService :  onGattReadRequest");

        }

        /**
         * Processes the Write Request from client and sends the response
         * to the client.
        */
        public void onGattReliableWriteRequest(BluetoothGattAppConfiguration config, int handle,
                        byte value[], String authentication, int sessionHandle,
                        int requestHandle) {
            System.out.println("FindMEService :  onGattReliableWriteRequest");

        }

        /**
         * Processes the Write Request from client and sends the response
         * to the client.
        */
        public void onGattWriteRequest(BluetoothGattAppConfiguration config, int handle,
                        byte value[], String authentication) {
            System.out.println("FindMEService :  onGattWriteRequest");

        }

        public void onGattSetClientConfigDescriptor(BluetoothGattAppConfiguration config,
                        int handle, byte[] value, int sessionHandle) {
            System.out.println("FindMEService :  onGattSetClientConfigDescriptor");
        }


    };

 // Unregister Gatt server application through Bluetooth Gatt API.
    private void unregistertoGATT() {
        Log.d(TAG, "FindMEService :  Unregister Server config called::");
        gattProfile.unregisterServerConfiguration(serverConfiguration);
    }

}

1

There are 1 best solutions below

1
On

Were you able to find the root cause. Since you have not posted yet so i am assumming may be you did not. From the shared source code, it is evident that your application uses BT-Low-energy stack from one of the many vendors like qualcomm, broadcomm and CSR. It would be helpful for you to understand the real reason for disconnect by actually taking the Air Sniffed logs of the scenario. Your FindMeService looks correct to me. however I personally would like to see Air Sniff logs.

Thanks and Cheers !!