Skip to content

Commit

Permalink
sensor mapping and matcher
Browse files Browse the repository at this point in the history
  • Loading branch information
grundid committed Nov 14, 2013
1 parent 02bc414 commit 8510bed
Show file tree
Hide file tree
Showing 10 changed files with 404 additions and 0 deletions.
20 changes: 20 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,24 @@
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>com.android</groupId>
<artifactId>platform</artifactId>
<version>19</version>
<systemPath>${env.ANDROID_HOME}/platforms/android-19/android.jar</systemPath>
<scope>system</scope>
</dependency>
<dependency>
<groupId>kxml2</groupId>
<artifactId>kxml2</artifactId>
<version>2.3.0</version>
<scope>test</scope>
</dependency>
</dependencies>

</project>
44 changes: 44 additions & 0 deletions src/main/java/de/grundid/ble/fingerprint/Sensor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package de.grundid.ble.fingerprint;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;

public class Sensor {

private String name;
private Map<UUID, Set<UUID>> services = new HashMap<UUID, Set<UUID>>();

public Sensor(String name) {
this.name = name;
}

public String getName() {
return name;
}

public void addService(UUID serviceUuid) {
services.put(serviceUuid, new HashSet<UUID>());
}

public void addCharacteristic(UUID serviceUuid, UUID charUuid) {
Set<UUID> service = services.get(serviceUuid);
service.add(charUuid);
}

public boolean hasService(UUID uuid) {
return services.containsKey(uuid);
}

public boolean hasCharacteristic(UUID serviceUuid, UUID characterictisUuid) {
Set<UUID> set = services.get(serviceUuid);
return set != null && set.contains(characterictisUuid);
}

public Set<Entry<UUID, Set<UUID>>> getServices() {
return services.entrySet();
}
}
37 changes: 37 additions & 0 deletions src/main/java/de/grundid/ble/fingerprint/SensorMatcher.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package de.grundid.ble.fingerprint;

import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;

public class SensorMatcher {

private List<Sensor> sensors;

public SensorMatcher(List<Sensor> sensors) {
this.sensors = sensors;
}

public String identifySensor(Sensor sensorToMatch) throws UnknownSensorException {
for (Sensor sensor : sensors) {
if (matchesSensor(sensor, sensorToMatch))
return sensor.getName();
}
throw new UnknownSensorException();
}

public boolean matchesSensor(Sensor sensor, Sensor sensorToMatch) {
for (Entry<UUID, Set<UUID>> entry : sensor.getServices()) {
UUID serviceUuid = entry.getKey();
if (!sensorToMatch.hasService(serviceUuid)) {
return false;
}
for (UUID charaUuid : entry.getValue()) {
if (!sensorToMatch.hasCharacteristic(serviceUuid, charaUuid))
return false;
}
}
return true;
}
}
104 changes: 104 additions & 0 deletions src/main/java/de/grundid/ble/fingerprint/SensorParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package de.grundid.ble.fingerprint;

import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;

import org.xmlpull.v1.XmlPullParser;

public class SensorParser {

private XmlPullParser xmlParser;

public SensorParser(XmlPullParser xmlParser) {
this.xmlParser = xmlParser;
}

private String getAttribute(String name) {
return xmlParser.getAttributeValue(null, name);
}

public static String toXml(Sensor sensor) {
StringBuilder sb = new StringBuilder();
sb.append("<sensor name=\"").append(sensor.getName()).append("\">");
for (Entry<UUID, Set<UUID>> entry : sensor.getServices()) {
sb.append("<service uuid=\"").append(entry.getKey().toString()).append("\">");
for (UUID characteristic : entry.getValue()) {
sb.append("<characteristic uuid=\"").append(characteristic.toString()).append("\" />");
}
sb.append("</service>");
}
sb.append("</sensor>");
return sb.toString();
}

public List<Sensor> parseSensors() {
try {
List<Sensor> result = new ArrayList<Sensor>();
int eventType = xmlParser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG) {
if ("sensors".equals(xmlParser.getName())) {
processSensors(result);
}
}
eventType = xmlParser.next();
}
return result;
}
catch (Exception e) {
throw new RuntimeException(e);
}
}

private void processSensors(List<Sensor> result) throws Exception {
int eventType = 0;
do {
eventType = xmlParser.next();
if (eventType == XmlPullParser.START_TAG) {
if ("sensor".equals(xmlParser.getName())) {
result.add(processSensor());
}
}
} while (eventType != XmlPullParser.END_TAG);
}

private Sensor processSensor() throws Exception {
Sensor sensor = new Sensor(getAttribute("name"));
int eventType = 0;
do {
eventType = xmlParser.next();
if (eventType == XmlPullParser.START_TAG) {
if ("service".equals(xmlParser.getName())) {
processService(sensor);
}
}
} while (eventType != XmlPullParser.END_TAG);
return sensor;
}

private void processService(Sensor sensor) throws Exception {
UUID serviceUuid = UUID.fromString(getAttribute("uuid"));
sensor.addService(serviceUuid);
int eventType = 0;
do {
eventType = xmlParser.next();
if (eventType == XmlPullParser.START_TAG) {
if ("characteristic".equals(xmlParser.getName())) {
sensor.addCharacteristic(serviceUuid, processCharacteristic());
}
}
} while (eventType != XmlPullParser.END_TAG);
}

private UUID processCharacteristic() throws Exception {
UUID uuid = UUID.fromString(getAttribute("uuid"));
int eventType = 0;
do {
eventType = xmlParser.next();
} while (eventType != XmlPullParser.END_TAG);
return uuid;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package de.grundid.ble.fingerprint;

public class UnknownSensorException extends Exception {
}
36 changes: 36 additions & 0 deletions src/main/java/de/grundid/ble/utils/BleUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package de.grundid.ble.utils;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;

import android.bluetooth.BluetoothGattCharacteristic;

public class BleUtils {

private static final Map<Integer, String> PROPERTIES = new LinkedHashMap<Integer, String>();
static {
PROPERTIES.put(BluetoothGattCharacteristic.PROPERTY_BROADCAST, "BC");
PROPERTIES.put(BluetoothGattCharacteristic.PROPERTY_READ, "RD");
PROPERTIES.put(BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE, "WN");
PROPERTIES.put(BluetoothGattCharacteristic.PROPERTY_WRITE, "WR");
PROPERTIES.put(BluetoothGattCharacteristic.PROPERTY_NOTIFY, "NY");
PROPERTIES.put(BluetoothGattCharacteristic.PROPERTY_INDICATE, "IN");
PROPERTIES.put(BluetoothGattCharacteristic.PROPERTY_SIGNED_WRITE, "SW");
PROPERTIES.put(BluetoothGattCharacteristic.PROPERTY_EXTENDED_PROPS, "EP");
}

public static String createPropertiesField(int flag) {
StringBuilder sb = new StringBuilder();
for (Entry<Integer, String> entry : PROPERTIES.entrySet()) {
int flagBit = entry.getKey().intValue();
if ((flag & flagBit) == flagBit) {
sb.append(entry.getValue());
}
else {
sb.append("--");
}
}
return sb.toString();
}
}
22 changes: 22 additions & 0 deletions src/test/java/de/grundid/ble/TestUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package de.grundid.ble;

import java.io.InputStream;

import org.kxml2.io.KXmlParser;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

public class TestUtils {

public static XmlPullParser createXmlPullParser(String resourceName) {
try {
InputStream inputStream = TestUtils.class.getClassLoader().getResourceAsStream(resourceName);
KXmlParser parser = new KXmlParser();
parser.setInput(inputStream, "utf8");
return parser;
}
catch (XmlPullParserException e) {
throw new RuntimeException(e);
}
}
}
61 changes: 61 additions & 0 deletions src/test/java/de/grundid/ble/fingerprint/SensorMatcherTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package de.grundid.ble.fingerprint;

import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import org.junit.Test;

public class SensorMatcherTest {

private static final String DEFAULT_UUID_SUFFIX = "-0000-1000-8000-00805f9b34fb";

@Test(expected = UnknownSensorException.class)
public void itShouldThrowExceptionIfNoMatch() throws Exception {
SensorMatcher matcher = new SensorMatcher(new ArrayList<Sensor>());
matcher.identifySensor(new Sensor("unknown"));
}

@Test
public void itShouldMatchSensor() throws Exception {
List<Sensor> sensors = new ArrayList<Sensor>();
sensors.add(appendService(new Sensor("s1"), "00001800", "00002a00"));
SensorMatcher matcher = new SensorMatcher(sensors);
Sensor sensorToMatch = new Sensor(null);
appendService(sensorToMatch, "00001800", "00002a00");
String name = matcher.identifySensor(sensorToMatch);
assertEquals("s1", name);
}

@Test
public void itShouldMatchSingleSensor() throws Exception {
SensorMatcher matcher = new SensorMatcher(null);
Sensor sensor = new Sensor("s1");
appendService(sensor, "00001800", "00002a00");
Sensor sensorToMatch = new Sensor(null);
appendService(sensorToMatch, "00001800", "00002a00");
assertTrue(matcher.matchesSensor(sensor, sensorToMatch));
}

@Test
public void itShouldMatchSensorWithMoreServices() throws Exception {
SensorMatcher matcher = new SensorMatcher(null);
Sensor sensor = new Sensor("s1");
appendService(sensor, "00001800", "00002a00");
Sensor sensorToMatch = new Sensor(null);
appendService(sensorToMatch, "00001800", "00002a00");
appendService(sensorToMatch, "0000180a", "00002a29");
assertTrue(matcher.matchesSensor(sensor, sensorToMatch));
}

private static Sensor appendService(Sensor sensor, String serviceUuid, String... charUuids) {
UUID uuid = UUID.fromString(serviceUuid + DEFAULT_UUID_SUFFIX);
sensor.addService(uuid);
for (String charUuid : charUuids) {
sensor.addCharacteristic(uuid, UUID.fromString(charUuid + DEFAULT_UUID_SUFFIX));
}
return sensor;
}
}
22 changes: 22 additions & 0 deletions src/test/java/de/grundid/ble/fingerprint/SensorParserTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package de.grundid.ble.fingerprint;

import static org.junit.Assert.*;

import java.util.List;

import org.junit.Test;
import org.xmlpull.v1.XmlPullParser;

import de.grundid.ble.TestUtils;

public class SensorParserTest {

@Test
public void itShouldParseSensors() throws Exception {
XmlPullParser xmlPullParser = TestUtils.createXmlPullParser("sensors.xml");
SensorParser parser = new SensorParser(xmlPullParser);
List<Sensor> sensors = parser.parseSensors();
assertNotNull(sensors);
assertEquals(2, sensors.size());
}
}
Loading

0 comments on commit 8510bed

Please sign in to comment.