Introduction to BoB standard by Samtrafiken
Standard defines that mobile ticket bundles (MTB-s) are signed both by issuer and the device itself. This helper library helps to construct device signed ticket bundles for Android devices more easily. Also this library can be used as a research basis for BoB standard in general as there are not many actual implementations that developers can use for examples.
This library is not (yet) published to any remote repositories, so first step is to actually checkout the code.
git clone https://github.com/tanieltari/bob-mtb.git
After checkout one must use platform specific Gradle wrapper script to run task called publishToMavenLocal
# Windows users
.\gradlew.bat publishToMavenLocal
# *nix users (Linux, MacOS etc)
./gradlew publishToMavenLocal
This will build the AAR file and publish it to the local Maven repository (~/.m2 directory)
Content resolver can be retrieved only from inside Activity
DeviceService deviceService = new DeviceService();
String deviceId = deviceService.getDeviceId(getContentResolver());
DeviceService deviceService = new DeviceService();
String deviceDateTime = deviceService.getDeviceDateTime();
Retrieving the authentication token from BoB Authentication API is developer responsibility
DeviceClient deviceClient = new DeviceClient();
DeviceKeyResponse deviceKeyResponse = deviceClient.getDeviceKey("https://device.bob.example.com/api/v1/device/key", deviceId, authToken);
Must define at least key, algorithm and device ID as defined in the standard
DeviceBundleHeader deviceBundleHeader = new DeviceBundleHeader();
deviceBundleHeader.setKeyId(deviceKeyResponse.getKeyId());
deviceBundleHeader.setAlgorithm("HS256");
deviceBundleHeader.setDeviceId(deviceId);
deviceBundleHeader.setTimestamp(deviceDateTime);
/* ... */
CompressorService compressorService = new CompressorService();
try {
byte[] compressedBytes = compressorService.compressBytesZlib(new byte[] {1, 2, 3});
} catch (IOException e) {
// Handle exception
}
try {
boolean isZlibBytes = compressorService.isZlibCompressed(new byte[] { 1, 2, 3 });
} catch (IOException e) {
// Handle exception
}
Last boolean in the method definition tells if MTB should be compressed or not
MtbService mtbService = new MtbService(compressorService);
try {
String issuerSignedMtb = mtbService.createDeviceSignedContainer(issuerMtb, deviceBundleHeader, deviceKeyResponse.getKey(), true);
} catch (IOException e) {
// Handle exception
}
Last integer in the method definition tells what ECC (error code correction) percentage should be used
AztecBarcode aztecBarcode = new AztecBarcode(compressorService);
try {
Bitmap mtbAztec = aztecBarcode.generateMtbBarcodeBitmap(issuerSignedMtb, 23);
} catch (IOException e) {
// Handle exception
}