I am doing some works with Texas Instruments SensorTag CC2541. I am trying to show the temperature data in the advertising packets.
First, I implemented the temperature service UUID in the advertising data packet. This is done in the SensorTag.c firmware (using IAR Workbench for 8051).
static uint8 advertData[] =
{
// Flags; this sets the device to use limited discoverable
// mode (advertises for 30 seconds at a time) instead of general
// discoverable mode (advertises indefinitely)
0x02, // length of this data
GAP_ADTYPE_FLAGS,
DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
0x03,
GAP_ADTYPE_16BIT_MORE,
LO_UINT16(IRTEMPERATURE_SERV_UUID),
HI_UINT16(IRTEMPERATURE_SERV_UUID)
};
Then, I use a sample Bluetooth Low Energy GAT application and modify it to show the data when it is scanning. The original app was used for another beacon device and it showed the beacon name + RSSI + thermometer service when scanning. Here is the original code:
class TemperatureBeacon {
/* Full Bluetooth UUID that defines the Health Thermometer Service */
public static final ParcelUuid THERM_SERVICE = ParcelUuid.fromString("00001809-0000-1000-8000-00805f9b34fb");
/* Short-form UUID that defines the Health Thermometer service */
private static final int UUID_SERVICE_THERMOMETER = 0x1809;
private String mName;
private float mCurrentTemp;
//Device metadata
private int mSignal;
private String mAddress;
/* Builder for Lollipop+ */
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public TemperatureBeacon(ScanRecord record, String deviceAddress, int rssi) {
mSignal = rssi;
mAddress = deviceAddress;
mName = record.getDeviceName();
byte[] data = record.getServiceData(THERM_SERVICE);
if (data != null) {
mCurrentTemp = parseTemp(data);
} else {
mCurrentTemp = 0f;
}
}
/* Builder for pre-Lollipop */
public TemperatureBeacon(List<AdRecord> records, String deviceAddress, int rssi) {
mSignal = rssi;
mAddress = deviceAddress;
for(AdRecord packet : records) {
//Find the device name record
if (packet.getType() == AdRecord.TYPE_NAME) {
mName = AdRecord.getName(packet);
}
//Find the service data record that contains our service's UUID
if (packet.getType() == AdRecord.TYPE_SERVICEDATA
&& AdRecord.getServiceDataUuid(packet) == UUID_SERVICE_THERMOMETER) {
byte[] data = AdRecord.getServiceData(packet);
mCurrentTemp = parseTemp(data);
}
}
}
private float parseTemp(byte[] serviceData) {
/*
* Temperature data is two bytes, and precision is 0.5degC.
* LSB contains temperature whole number
* MSB contains a bit flag noting if fractional part exists
*/
float temp = (serviceData[0] & 0xFF);
if ((serviceData[1] & 0x80) != 0) {
temp += 0.5f;
}
return temp;
}
public String getName() {
return mName;
}
public int getSignal() {
return mSignal;
}
public float getCurrentTemp() {
return mCurrentTemp;
}
public String getAddress() {
return mAddress;
}
@Override
public String toString() {
return String.format("%s (%ddBm): %.1fC", mName, mSignal, mCurrentTemp);
}
}
As you can see, the program uses the THERM_SERVICE UUID (00001809-0000-1000-8000-00805f9b34fb) and its short form (0x1809). I tried to modify it with the SensorTag IR Temperature UUID service (F000AA00-0451-4000-B000-000000000000). And the result is that, it cannot show neither the name of the scanned device nor the temperature data.
Can you give some suggestions for this problem? Thank you!