Reverse Engineering iTag – A Bluetooth Low Energy Button

Couple of weeks back I bought a few iTags. These are simple BLE buttons. They have a small led, a button and a buzzer. CR2032 - a 3v coin cell battery powers it. Since they are Bluetooth Low Energy devices, a single cell can power them for years. It's easy to change batteries if they run out of power. Bought individually they cost about ₹200 but on AliBaba you can buy a dozen for ₹1500. They are usually used with phones as an extra remote button or as a leash for key chain. I wanted to use them as a remote button with an App I was building. Hence the reverse engineering.

I began with installing nRF Connect android App. nRF Connect is a BLE Swiss army knife. You can scan, advertise and explore BLE devices with it. You can also connect and communicate with them.

<server-configuration name="iTag">
<!-- BATTERY_SERVICE -->
   <service uuid="0000180f-0000-1000-8000-00805f9b34fb">
      <characteristic uuid="00002a19-0000-1000-8000-00805f9b34fb">
         <descriptor configure="CCCD"/>
         <permission name="READ"/>
         <property name="READ"/>
         <property name="NOTIFY"/>
      </characteristic>
   </service>
   <!-- IMMEDIATE ALERT SERVICE -->
   <service uuid="00001802-0000-1000-8000-00805f9b34fb">
      <characteristic uuid="00002a06-0000-1000-8000-00805f9b34fb">
         <descriptor configure="CCCD"/>
         <permission name="WRITE"/>
         <property name="WRITE"/>
         <property name="WRITE_WITHOUT_RESPONSE"/>
         <property name="NOTIFY"/>
      </characteristic>
   </service>
   <!-- SIMPLE KEY OR BUTTON SERVICE -->
   <service uuid="0000ffe0-0000-1000-8000-00805f9b34fb">
      <characteristic uuid="0000ffe1-0000-1000-8000-00805f9b34fb">
         <descriptor configure="CCCD"/>
         <permission name="READ"/>
         <property name="READ"/>
         <property name="NOTIFY"/>
      </characteristic>
   </service>
</server-configuration>

Once you connect to the iTag using nRF connect, you can explore the services and characteristics. You can also press the button on iTag to see which characteristic changes. I have the XML above which is the copy of ITag services and characteristics. Its copied using nRF connect. You can see it supports two standard services Battery service and Immediate alert service. They are very well-defined and works as defined.

The third one which is a custom service is the interesting one. It is attached to the button. It sends a notification when the button is clicked. On a client (Eg: Mobile app) you can subscribe to notification on this characteristics. You will get notified every time the button gets clicked.

Play store has many apps that can be used with iTags. They provide options like taking a selfie using the button etc. There are other apps which allow you to attach events to tasker app. I found an open source app called ITracing2. This one is the most versatile app that allows you to send events to other apps or internet. The app code is clean and very readable. Since I was studying the protocol, I took time to read code and fixed a bug while I was there. Hence this is my recommended app :) I use this app in two ways. The diagram clearly shows the flow of event. You can set up these flows the Itracing App. Itracing App also provides the feature of double-click. Two successive clicks from iTag button within a preset time period is a double-click. I have this double-click period set as 300ms. You can change this period. So if I click the button twice within 300ms then its a double-click else single click. That gives an extra event for us to play with.

Other than these generic app setups. If you are an app developer then you can integrate this feature into your own app. Almost every iTag manufacturer now uses characteristics 0000ffe1-0000-1000-8000-00805f9b34fb to send button click. It's almost a standard now. So if your app needs an external button feature then this is an option.

On Android its super simple. Enable notification of the simple key service and characteristics.

//Define UUID
public static final UUID FIND_ME_SERVICE = UUID.fromString("0000ffe0-0000-1000-8000-00805f9b34fb");
public static final UUID FIND_ME_CHARACTERISTIC = UUID.fromString("0000ffe1-0000-1000-8000-00805f9b34fb");

//once you discovered services, enable notificaton
@Override
public void onServicesDiscovered(final BluetoothGatt gatt, int status) {
//....
//....
for (BluetoothGattService service : gatt.getServices()) {
  if (FIND_ME_SERVICE.equals(service.getUuid())) {
        if (!service.getCharacteristics().isEmpty()) {
            buttonCharacteristic = service.getCharacteristics().get(0);
            setCharacteristicNotification(gatt, buttonCharacteristic, true);
        }
  }
}
//....
//....
}//end of onServicesDiscovered


//enable notifcations by setting the respective config flag
private void setCharacteristicNotification(BluetoothGatt bluetoothgatt, BluetoothGattCharacteristic bluetoothgattcharacteristic, boolean flag) {
	//enable notification
    bluetoothgatt.setCharacteristicNotification(bluetoothgattcharacteristic, flag);
    if (FIND_ME_CHARACTERISTIC.equals(bluetoothgattcharacteristic.getUuid())) {
        BluetoothGattDescriptor descriptor = bluetoothgattcharacteristic.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG);
        if (descriptor != null) {
            descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
            bluetoothgatt.writeDescriptor(descriptor);
        }
    }
}



//when the remote notification gets changed, call back gets called. 
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
//Do whatever you want to do here
}

if you are react native fan its equally easy using react-native-ble-manager

const FIND_ME_SERVICE = "0000ffe0-0000-1000-8000-00805f9b34fb";
const FIND_ME_CHARACTERISTIC = "0000ffe1-0000-1000-8000-00805f9b34fb";

constructor(){
    //......
    //register all other handlers	
    //this is what gets called when the value changes or notification comes in
    this.handleUpdateValueForCharacteristic = this.handleUpdateValueForCharacteristic.bind(this);
    //......
}

//register for notification
BleManager.startNotification(peripheral, FIND_ME_SERVICE, FIND_ME_CHARACTERISTIC).then(() => {
	console.log('Notification started');
}).catch((error) => {
  console.log('Notification error', error);
  reject(error);
});


//Handle when the notification comes in
handleUpdateValueForCharacteristic(data) {
	console.log('Received '+ data.value + ' from ' + data.peripheral + ' characteristic ' + data.characteristic);
	if(data.characteristic == FIND_ME_CHARACTERISTIC ){
	  //do what you want to do when button is pressed
	} 
}

Let me know if you have any questions or used the button in an innovative way. I would love to hear.

A note about Privacy; These low-cost iTags have a hard-coded mac address. Hence they can be tracked quite easily. This is something that you need to keep in mind. I will write about BLE privacy issues later.

17 Responses

  1. Andrew says:

    I want to use mine as a keyfinder, but the problem is, when it goes out of range, it starts beeping, which is annoying. It also has a power saving mode that shuts it down if it isn’t connected to anything.

    Ideally, my plan would be to reprogram it to disable the power saving mode, so that I can connect to the device only whenever I lose it.

  2. Juanj says:

    Do you know of is there a way to turn off the power saving feature? It is useless as a finding device it switches off when out of range.

  3. Thanx for this article, I was looking for something to recognize key presses on BLE tracker and found about iTracking2 here… great software. I have been googling like 30 minutes on how to integrate BLE tag with Tasker and this is the only article that sucessfully deals with it :) Thanx!

  4. nobios says:

    Hi. Nice write up and I appreciate all the work you have done. I just purchased one of these BLE tags and I would like to create a tasker event with the help of iTracing2 call broadcast intent function. My problem is that I don’t know how to get started. I would like to use my iTag for opening Google Voice Search on my phone when I press the button in the iTag.

    I want to call broadcast intent with iTracing2 and receive it with Tasker. I just don’t know how to set up this intent.

  5. Tomáš Doležal says:

    Hi, still same question – is there any way to disable sleep timer in ITAG? :-( 15min off timer without connection to BT. Doesn’t make sense to use for searching of lost keys… :-(

  6. User says:

    Can a person use that device to make his own software using it….

  7. Carol Lemaster says:

    My itag is turned off . Now my keys are lost and I cant use itag because it is not in. Any suggestions

  8. Vc says:

    someone got answered? This battery saving mode can be switched for full time sending mode?

  9. jyoti says:

    Hi, I always get descriptor as null though i used same as in code .Could You plz tell me why descriptor is null everytime

  10. Allen says:

    has anyone figured out how to turn of this “power saver” or autoshutoff? if you could disable that on these – would be a lot more useful.
    as is you that shut off and become useless.
    anyone any solution?

  11. Aleksandra Maria Czajka says:

    Thejesh,
    Thank you for your wonderful article! I’m looking to connect to a bluetooth camera and take a picture with it using a React Native application. Could you point me to any articles on such a React Native implementation or provide some suggestions. All help is appreciated in advance!
    All my best,
    Aleks

  12. Ammaross says:

    Hello ,
    Thnks for this article
    i wonder why my iTag dosent show up ? it can’t be detected ?!

  13. Amit Kumar says:

    Just want to know two things about itag . First what is the purpose of the pin hole,just below big ring and above button. Second, how it can be used for parking site searching as claimed.

  14. Misiu says:

    Any news about power mode? I want to use ESP32 to track when my kids get home. I can’t expect them to press the buttons. I need the iTag to send data even when it is not connected to phone.

  15. Nilanjan Das says:

    Hello,
    I am Neel, and I am working on a concept device and app. I would like to discuss the details with you. Please reach out to me if you are interested in more details.

  1. July 9, 2021

    […] “Reverse Engineering iTag – A Bluetooth Low Energy Button | Thejesh GN” […]