diff --git a/.gitignore b/.gitignore index dece6c5..e632471 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ bin/ gen/ MANIFEST.MF build.num +*.java_ # Local configuration file (sdk path, etc) local.properties @@ -22,6 +23,11 @@ dist/ /.idea /.gradle /build -/SmartGattLib.iml -/SmartGattLib.ipr -/SmartGattLib.iws +*.iml +*.ipr +*.iws + +# eclipse files +.project +.classpath +.settings/ \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..144a637 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,47 @@ + +# [3.6.0] + +- added application level encryption for over the air data +- added method getOutgoingData to AbstractAttribute that replaces the method getBytes and needs CryptoManager as argument +- added alternative signature for Characteristic.createAttribute: added new parameter for CryptoManager +- to get the raw data representation of an attribute the method getRawData was added to AbstractAttribute + + +# [3.2.0] (2019-09-03) + + - Added putMstime to GattByteBuffer + + +# [3.1.0] (2019-02-21) + + - Added getCharacteristics to obtain all Characteristics as a Collection + + +# [3.0.0](https://github.com/movisens/SmartGattLib/compare/v2.1...v3.0) (2017-11-07) + +This release comes with a significant api change to simplify + +### Upgrade Instructions + +* replace ```com.movisens.smartgattlib.Service``` with ```com.movisens.smartgattlib.Services``` +* replace ```com.movisens.smartgattlib.Characteristic``` with ```com.movisens.smartgattlib.Characteristics``` + +It is now possible to parse Characteristics with: +``` java +AbstractAttribute a = Characteristics.lookup(uuid).createAttribute(data); +if (a instanceof HeartRateMeasurement) { + HeartRateMeasurement heartRateMeasurement = ((HeartRateMeasurement) a); + heartRateMeasurement.getHr(); + heartRateMeasurement.getEe(); +} else if (a instanceof DefaultAttribute) { + System.err.println("characteristic for " + uuid + " is unknown"); +} else { + System.out.println("unused characteristic " + a.getCharacteristic().getName()); +} +``` + +It is also possible to write Characteristics and convert them to bytes: +``` java +AbstractAttribute aa = new Weight(12.3); +// TODO: Write aa.getBytes() to aa.getCharacteristic().getUuid(); +``` \ No newline at end of file diff --git a/README.md b/README.md index f49442a..a35d88d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ SmartGattLib ============ - + SmartGattLib is a Java library that simplifies the work with **Bluetooth SMART** devices (a.k.a. **Bluetooth Low Energy** in Bluetooth 4.0). It provides all UUIDs of the adopted [GATT specification](http://developer.bluetooth.org/gatt/Pages/default.aspx) and an convenient way to interpret the characteristics (e.g. Heart Rate, BatteryLevel). @@ -16,9 +16,7 @@ SmartGattLib is a Java library that simplifies the work with **Bluetooth SMART** The library has **no dependencies** and can be use with **every Bluetooth SMART stack** e.g.: * [Android API Level 18](http://developer.android.com/guide/topics/connectivity/bluetooth-le.html) - * [Samsung BLE SDK](http://developer.samsung.com/ble) - * [HTC OpenSense BLE API](http://www.htcdev.com/devcenter/opensense-sdk/partner-apis/bluetooth-low-energy/) - * Motorola (seems obsolete) + * [RxAndroidBle](https://github.com/Polidea/RxAndroidBle) ### Integration ### Working with Bluetooth SMART devices is usually done in the following way: @@ -41,7 +39,7 @@ Example Android project with SmartGattLib available [here](https://github.com/mo maven { url "https://jitpack.io/" } } dependencies { - compile 'com.github.movisens:SmartGattLib:1.7' + compile 'com.github.movisens:SmartGattLib:3.6' } ``` or download the latest .jar file from the [releases](https://github.com/movisens/SmartGattLib/releases) page and place it in your Android app’s libs/ folder. @@ -50,34 +48,47 @@ Example Android project with SmartGattLib available [here](https://github.com/mo ### Example Usage ### ```java import com.movisens.smartgattlib.*; +import com.movisens.smartgattlib.attributes.*; +import com.movisens.smartgattlib.helper.*; // onConnected -//TODO: iterate over available services -UUID serviceUuid = service.getUuid(); -if (Service.HEART_RATE.equals(serviceUuid)) { // Identify Service - //TODO: iterate over characteristics - UUID characteristicUuid = characteristic.getUuid(); - if (Characteristic.HEART_RATE_MEASUREMENT.equals(characteristicUuid)) { // Identify Characteristic - // TODO: Enable notification e.g. for Android API 18: - // BluetoothGattDescriptor descriptor = characteristic.getDescriptor(Descriptor.CLIENT_CHARACTERISTIC_CONFIGURATION); - // descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); - // mBluetoothGatt.writeDescriptor(descriptor); - } -}else{ - System.out.println("Found unused Service: " + Service.lookup(serviceUuid, "unknown")); +// TODO: iterate over available services +UUID serviceUuid = null;// service.getUuid(); +if (Services.HEART_RATE.getUuid().equals(serviceUuid)) { + + // TODO: iterate over characteristics + UUID characteristicUuid = null;// characteristic.getUuid(); + if (Characteristics.HEART_RATE_MEASUREMENT.getUuid().equals(characteristicUuid)) { + // TODO: Enable notification e.g. for Android API 18: + // BluetoothGattDescriptor descriptor = characteristic.getDescriptor(Descriptor.CLIENT_CHARACTERISTIC_CONFIGURATION); + // descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); + // mBluetoothGatt.writeDescriptor(descriptor); + } +} else { + System.out.println("Found unused Service: " + Services.lookup(serviceUuid)); } // onCharacteristicChanged -UUID characteristicUuid = characteristic.getUuid(); -if (Characteristic.HEART_RATE_MEASUREMENT.equals(characteristicUuid)) { // Identify Characteristic - byte[] value = characteristic.getValue(); - HeartRateMeasurement hrm = new HeartRateMeasurement(value); // Interpret Characteristic - System.out.println("HR: " + hrm.getHr() + "bpm"); - System.out.println("EE: " + hrm.getEe() + "kJ"); +UUID uuid = null;// characteristic.getUuid(); +byte[] data = null;// characteristic.getValue(); + +AbstractAttribute a = Characteristics.lookup(uuid).createAttribute(data); +if (a instanceof HeartRateMeasurement) { + HeartRateMeasurement heartRateMeasurement = ((HeartRateMeasurement) a); + heartRateMeasurement.getHr(); + heartRateMeasurement.getEe(); +} else if (a instanceof DefaultAttribute) { + System.err.println("characteristic for " + uuid + " is unknown"); +} else { + System.out.println("unused characteristic " + a.getCharacteristic().getName()); } + +// write Attribute +AbstractAttribute aa = new Weight(12.3); +// TODO: Write aa.getBytes() to aa.getCharacteristic().getUuid(); ``` ### License ### -Copyright 2013 movisens GmbH +Copyright 2017 movisens GmbH Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/build.gradle b/build.gradle index 67a4960..cb016cb 100644 --- a/build.gradle +++ b/build.gradle @@ -1,27 +1,47 @@ -/* - * This build file was auto generated by running the Gradle 'init' task - * by 'Juergen' at '15.03.15 19:57' with Gradle 1.11 - * - * This generated file contains a sample Java project to get you started. - * For more details take a look at the Java Quickstart chapter in the Gradle - * user guide available at http://gradle.org/docs/1.11/userguide/tutorial_java_projects.html - */ - -// Apply the java plugin to add support for Java -apply plugin: 'java' -apply plugin: 'eclipse' -apply plugin: 'idea' -apply plugin: 'maven' +apply plugin: 'java-library' +apply plugin: 'maven-publish' group = 'com.github.movisens' -targetCompatibility = 1.6 -sourceCompatibility = 1.6 +targetCompatibility = 1.8 +sourceCompatibility = 1.8 + +compileJava.options.encoding = 'UTF-8' +compileTestJava.options.encoding = 'UTF-8' + +version = '3.6.0' repositories { mavenCentral() } dependencies { - testCompile group: 'junit', name: 'junit', version: '4.11' -} \ No newline at end of file + testImplementation group: 'junit', name: 'junit', version: '4.11' +} + +sourceSets { + main { + java { + srcDir('src-gen/main/java') + } + } +} + +//OSGI specific entries that are not automatically generated +jar { + manifest { + attributes ( + 'Bundle-SymbolicName': project.group + project.name, + 'Bundle-Version': project.version, + 'Export-Package': 'com.movisens.smartgattlib, com.movisens.smartgattlib.*' + ) + } +} + +publishing { + publications { + maven(MavenPublication) { + from components.java + } + } +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 3d0dee6..7454180 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 508df78..2ec77e5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Sun Mar 15 19:58:12 CET 2015 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.1-bin.zip diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 index 91a7e26..1b6c787 --- a/gradlew +++ b/gradlew @@ -1,79 +1,129 @@ -#!/usr/bin/env bash +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum -warn ( ) { +warn () { echo "$*" -} +} >&2 -die ( ) { +die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -82,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" + JAVACMD=java which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the @@ -90,75 +140,95 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=$((i+1)) + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 8a0b282..107acd3 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,3 +1,19 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @@ -8,20 +24,23 @@ @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -35,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -45,34 +64,14 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell diff --git a/settings.gradle b/settings.gradle index b805aab..39b7886 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,19 +1,2 @@ -/* - * This settings file was auto generated by the Gradle buildInit task - * by 'Juergen' at '15.03.15 19:57' with Gradle 1.11 - * - * The settings file is used to specify which projects to include in your build. - * In a single project build this file can be empty or even removed. - * - * Detailed information about configuring a multi-project build in Gradle can be found - * in the user guide at http://gradle.org/docs/1.11/userguide/multi_project_builds.html - */ - -/* -// To declare projects as part of a multi-project build use the 'include' method -include 'shared' -include 'api' -include 'services:webservice' -*/ - rootProject.name = 'SmartGattLib' + diff --git a/src-gen/main/java/com/movisens/smartgattlib/Characteristics.java b/src-gen/main/java/com/movisens/smartgattlib/Characteristics.java new file mode 100644 index 0000000..910649b --- /dev/null +++ b/src-gen/main/java/com/movisens/smartgattlib/Characteristics.java @@ -0,0 +1,469 @@ +package com.movisens.smartgattlib; + +import java.util.Collection; +import java.util.UUID; + +import com.movisens.smartgattlib.attributes.DefaultAttribute; +import com.movisens.smartgattlib.helper.Characteristic; +import com.movisens.smartgattlib.helper.UuidObjectMap; +import com.movisens.smartgattlib.helper.AbstractAttribute; +import com.movisens.smartgattlib.attributes.*; + +public class Characteristics +{ + + public static final Characteristic DEFAULT = new Characteristic("0000", "Default Characteristic", DefaultAttribute.class); + public static final Characteristic LONGITUDE = new Characteristic("2aaf", "Longitude", DefaultAttribute.class); + public static final Characteristic MAGNETIC_FLUX_DENSITY_2D = new Characteristic("2aa0", "Magnetic Flux Density - 2D", DefaultAttribute.class); + public static final Characteristic MAGNETIC_FLUX_DENSITY_3D = new Characteristic("2aa1", "Magnetic Flux Density - 3D", DefaultAttribute.class); + public static final Characteristic AEROBIC_HEART_RATE_LOWER_LIMIT = new Characteristic("2a7e", "Aerobic Heart Rate Lower Limit", DefaultAttribute.class); + public static final Characteristic AEROBIC_HEART_RATE_UPPER_LIMIT = new Characteristic("2a84", "Aerobic Heart Rate Upper Limit", DefaultAttribute.class); + public static final Characteristic AEROBIC_THRESHOLD = new Characteristic("2a7f", "Aerobic Threshold", DefaultAttribute.class); + public static final Characteristic AGE = new Characteristic("2a80", "Age", Age.class); + public static final Characteristic AGGREGATE = new Characteristic("2a5a", "Aggregate", DefaultAttribute.class); + public static final Characteristic ALERT_CATEGORY_ID = new Characteristic("2a43", "Alert Category ID", DefaultAttribute.class); + public static final Characteristic ALERT_CATEGORY_ID_BIT_MASK = new Characteristic("2a42", "Alert Category ID Bit Mask", DefaultAttribute.class); + public static final Characteristic ALERT_LEVEL = new Characteristic("2a06", "Alert Level", DefaultAttribute.class); + public static final Characteristic ALERT_NOTIFICATION_CONTROL_POINT = new Characteristic("2a44", "Alert Notification Control Point", DefaultAttribute.class); + public static final Characteristic ALERT_STATUS = new Characteristic("2a3f", "Alert Status", DefaultAttribute.class); + public static final Characteristic ALTITUDE = new Characteristic("2ab3", "Altitude", DefaultAttribute.class); + public static final Characteristic ANAEROBIC_HEART_RATE_LOWER_LIMIT = new Characteristic("2a81", "Anaerobic Heart Rate Lower Limit", DefaultAttribute.class); + public static final Characteristic ANAEROBIC_HEART_RATE_UPPER_LIMIT = new Characteristic("2a82", "Anaerobic Heart Rate Upper Limit", DefaultAttribute.class); + public static final Characteristic ANAEROBIC_THRESHOLD = new Characteristic("2a83", "Anaerobic Threshold", DefaultAttribute.class); + public static final Characteristic ANALOG = new Characteristic("2a58", "Analog", DefaultAttribute.class); + public static final Characteristic ANALOG_OUTPUT = new Characteristic("2a59", "Analog Output", DefaultAttribute.class); + public static final Characteristic APPARENT_WIND_DIRECTION = new Characteristic("2a73", "Apparent Wind Direction", DefaultAttribute.class); + public static final Characteristic APPARENT_WIND_SPEED = new Characteristic("2a72", "Apparent Wind Speed", DefaultAttribute.class); + public static final Characteristic APPEARANCE = new Characteristic("2a01", "Appearance", Appearance.class); + public static final Characteristic BAROMETRIC_PRESSURE_TREND = new Characteristic("2aa3", "Barometric Pressure Trend", DefaultAttribute.class); + public static final Characteristic BATTERY_LEVEL = new Characteristic("2a19", "Battery Level", BatteryLevel.class); + public static final Characteristic BATTERY_LEVEL_STATE = new Characteristic("2a1b", "Battery Level State", DefaultAttribute.class); + public static final Characteristic BATTERY_POWER_STATE = new Characteristic("2a1a", "Battery Power State", DefaultAttribute.class); + public static final Characteristic BLOOD_PRESSURE_FEATURE = new Characteristic("2a49", "Blood Pressure Feature", DefaultAttribute.class); + public static final Characteristic BLOOD_PRESSURE_MEASUREMENT = new Characteristic("2a35", "Blood Pressure Measurement", DefaultAttribute.class); + public static final Characteristic BODY_COMPOSITION_FEATURE = new Characteristic("2a9b", "Body Composition Feature", DefaultAttribute.class); + public static final Characteristic BODY_COMPOSITION_MEASUREMENT = new Characteristic("2a9c", "Body Composition Measurement", DefaultAttribute.class); + public static final Characteristic BODY_SENSOR_LOCATION = new Characteristic("2a38", "Body Sensor Location", BodySensorLocation.class); + public static final Characteristic BOND_MANAGEMENT_CONTROL_POINT = new Characteristic("2aa4", "Bond Management Control Point", DefaultAttribute.class); + public static final Characteristic BOND_MANAGEMENT_FEATURE = new Characteristic("2aa5", "Bond Management Features", DefaultAttribute.class); + public static final Characteristic BOOT_KEYBOARD_INPUT_REPORT = new Characteristic("2a22", "Boot Keyboard Input Report", DefaultAttribute.class); + public static final Characteristic BOOT_KEYBOARD_OUTPUT_REPORT = new Characteristic("2a32", "Boot Keyboard Output Report", DefaultAttribute.class); + public static final Characteristic BOOT_MOUSE_INPUT_REPORT = new Characteristic("2a33", "Boot Mouse Input Report", DefaultAttribute.class); + public static final Characteristic CGM_FEATURE = new Characteristic("2aa8", "CGM Feature", DefaultAttribute.class); + public static final Characteristic CGM_MEASUREMENT = new Characteristic("2aa7", "CGM Measurement", DefaultAttribute.class); + public static final Characteristic CGM_SESSION_RUN_TIME = new Characteristic("2aab", "CGM Session Run Time", DefaultAttribute.class); + public static final Characteristic CGM_SESSION_START_TIME = new Characteristic("2aaa", "CGM Session Start Time", DefaultAttribute.class); + public static final Characteristic CGM_SPECIFIC_OPS_CONTROL_POINT = new Characteristic("2aac", "CGM Specific Ops Control Point", DefaultAttribute.class); + public static final Characteristic CGM_STATUS = new Characteristic("2aa9", "CGM Status", DefaultAttribute.class); + public static final Characteristic CROSS_TRAINER_DATA = new Characteristic("2ace", "Cross Trainer Data", DefaultAttribute.class); + public static final Characteristic CSC_FEATURE = new Characteristic("2a5c", "CSC Feature", DefaultAttribute.class); + public static final Characteristic CSC_MEASUREMENT = new Characteristic("2a5b", "CSC Measurement", CscMeasurement.class); + public static final Characteristic CURRENT_TIME = new Characteristic("2a2b", "Current Time", DefaultAttribute.class); + public static final Characteristic CYCLING_POWER_CONTROL_POINT = new Characteristic("2a66", "Cycling Power Control Point", DefaultAttribute.class); + public static final Characteristic CYCLING_POWER_FEATURE = new Characteristic("2a65", "Cycling Power Feature", DefaultAttribute.class); + public static final Characteristic CYCLING_POWER_MEASUREMENT = new Characteristic("2a63", "Cycling Power Measurement", DefaultAttribute.class); + public static final Characteristic CYCLING_POWER_VECTOR = new Characteristic("2a64", "Cycling Power Vector", DefaultAttribute.class); + public static final Characteristic DATABASE_CHANGE_INCREMENT = new Characteristic("2a99", "Database Change Increment", DefaultAttribute.class); + public static final Characteristic DATE_OF_BIRTH = new Characteristic("2a85", "Date of Birth", DateOfBirth.class); + public static final Characteristic DATE_OF_THRESHOLD_ASSESSMENT = new Characteristic("2a86", "Date of Threshold Assessment", DefaultAttribute.class); + public static final Characteristic DATE_TIME = new Characteristic("2a08", "Date Time", DefaultAttribute.class); + public static final Characteristic DAY_DATE_TIME = new Characteristic("2a0a", "Day Date Time", DefaultAttribute.class); + public static final Characteristic DAY_OF_WEEK = new Characteristic("2a09", "Day of Week", DefaultAttribute.class); + public static final Characteristic DESCRIPTOR_VALUE_CHANGED = new Characteristic("2a7d", "Descriptor Value Changed", DefaultAttribute.class); + public static final Characteristic DEVICE_NAME = new Characteristic("2a00", "Device Name", DeviceName.class); + public static final Characteristic DEW_POINT = new Characteristic("2a7b", "Dew Point", DefaultAttribute.class); + public static final Characteristic DIGITAL = new Characteristic("2a56", "Digital", DefaultAttribute.class); + public static final Characteristic DIGITAL_OUTPUT = new Characteristic("2a57", "Digital Output", DefaultAttribute.class); + public static final Characteristic DST_OFFSET = new Characteristic("2a0d", "DST Offset", DefaultAttribute.class); + public static final Characteristic ELEVATION = new Characteristic("2a6c", "Elevation", DefaultAttribute.class); + public static final Characteristic EMAIL_ADDRESS = new Characteristic("2a87", "Email Address", DefaultAttribute.class); + public static final Characteristic EXACT_TIME_100 = new Characteristic("2a0b", "Exact Time 100", DefaultAttribute.class); + public static final Characteristic EXACT_TIME_256 = new Characteristic("2a0c", "Exact Time 256", DefaultAttribute.class); + public static final Characteristic FAT_BURN_HEART_RATE_LOWER_LIMIT = new Characteristic("2a88", "Fat Burn Heart Rate Lower Limit", DefaultAttribute.class); + public static final Characteristic FAT_BURN_HEART_RATE_UPPER_LIMIT = new Characteristic("2a89", "Fat Burn Heart Rate Upper Limit", DefaultAttribute.class); + public static final Characteristic FIRMWARE_REVISION_STRING = new Characteristic("2a26", "Firmware Revision String", FirmwareRevisionString.class); + public static final Characteristic FIRST_NAME = new Characteristic("2a8a", "First Name", DefaultAttribute.class); + public static final Characteristic FITNESS_MACHINE_CONTROL_POINT = new Characteristic("2ad9", "Fitness Machine Control Point", DefaultAttribute.class); + public static final Characteristic FITNESS_MACHINE_FEATURE = new Characteristic("2acc", "Fitness Machine Feature", DefaultAttribute.class); + public static final Characteristic FITNESS_MACHINE_STATUS = new Characteristic("2ada", "Fitness Machine Status", DefaultAttribute.class); + public static final Characteristic FIVE_ZONE_HEART_RATE_LIMITS = new Characteristic("2a8b", "Five Zone Heart Rate Limits", DefaultAttribute.class); + public static final Characteristic FLOOR_NUMBER = new Characteristic("2ab2", "Floor Number", DefaultAttribute.class); + public static final Characteristic GENDER = new Characteristic("2a8c", "Gender", Gender.class); + public static final Characteristic GLUCOSE_FEATURE = new Characteristic("2a51", "Glucose Feature", DefaultAttribute.class); + public static final Characteristic GLUCOSE_MEASUREMENT = new Characteristic("2a18", "Glucose Measurement", DefaultAttribute.class); + public static final Characteristic GLUCOSE_MEASUREMENT_CONTEXT = new Characteristic("2a34", "Glucose Measurement Context", DefaultAttribute.class); + public static final Characteristic GUST_FACTOR = new Characteristic("2a74", "Gust Factor", DefaultAttribute.class); + public static final Characteristic HARDWARE_REVISION_STRING = new Characteristic("2a27", "Hardware Revision String", DefaultAttribute.class); + public static final Characteristic HEART_RATE_CONTROL_POINT = new Characteristic("2a39", "Heart Rate Control Point", DefaultAttribute.class); + public static final Characteristic HEART_RATE_MAX = new Characteristic("2a8d", "Heart Rate Max", DefaultAttribute.class); + public static final Characteristic HEART_RATE_MEASUREMENT = new Characteristic("2a37", "Heart Rate Measurement", HeartRateMeasurement.class); + public static final Characteristic HEAT_INDEX = new Characteristic("2a7a", "Heat Index", DefaultAttribute.class); + public static final Characteristic HEIGHT = new Characteristic("2a8e", "Height", Height.class); + public static final Characteristic HID_CONTROL_POINT = new Characteristic("2a4c", "HID Control Point", DefaultAttribute.class); + public static final Characteristic HID_INFORMATION = new Characteristic("2a4a", "HID Information", DefaultAttribute.class); + public static final Characteristic HIP_CIRCUMFERENCE = new Characteristic("2a8f", "Hip Circumference", DefaultAttribute.class); + public static final Characteristic HTTP_CONTROL_POINT = new Characteristic("2aba", "HTTP Control Point", DefaultAttribute.class); + public static final Characteristic HTTP_ENTITY_BODY = new Characteristic("2ab9", "HTTP Entity Body", DefaultAttribute.class); + public static final Characteristic HTTP_HEADERS = new Characteristic("2ab7", "HTTP Headers", DefaultAttribute.class); + public static final Characteristic HTTP_STATUS_CODE = new Characteristic("2ab8", "HTTP Status Code", DefaultAttribute.class); + public static final Characteristic HTTPS_SECURITY = new Characteristic("2abb", "HTTPS Security", DefaultAttribute.class); + public static final Characteristic HUMIDITY = new Characteristic("2a6f", "Humidity", DefaultAttribute.class); + public static final Characteristic IEEE_11073_20601_REGULATORY_CERTIFICATION_DATA_LIST = new Characteristic("2a2a", "IEEE 11073-20601 Regulatory Certification Data List", DefaultAttribute.class); + public static final Characteristic INDOOR_BIKE_DATA = new Characteristic("2ad2", "Indoor Bike Data", DefaultAttribute.class); + public static final Characteristic INDOOR_POSITIONING_CONFIGURATION = new Characteristic("2aad", "Indoor Positioning Configuration", DefaultAttribute.class); + public static final Characteristic INTERMEDIATE_CUFF_PRESSURE = new Characteristic("2a36", "Intermediate Cuff Pressure", DefaultAttribute.class); + public static final Characteristic INTERMEDIATE_TEMPERATURE = new Characteristic("2a1e", "Intermediate Temperature", DefaultAttribute.class); + public static final Characteristic IRRADIANCE = new Characteristic("2a77", "Irradiance", DefaultAttribute.class); + public static final Characteristic LANGUAGE = new Characteristic("2aa2", "Language", DefaultAttribute.class); + public static final Characteristic LAST_NAME = new Characteristic("2a90", "Last Name", DefaultAttribute.class); + public static final Characteristic LATITUDE = new Characteristic("2aae", "Latitude", DefaultAttribute.class); + public static final Characteristic LN_CONTROL_POINT = new Characteristic("2a6b", "LN Control Point", DefaultAttribute.class); + public static final Characteristic LN_FEATURE = new Characteristic("2a6a", "LN Feature", DefaultAttribute.class); + public static final Characteristic LOCAL_EAST_COORDINATE = new Characteristic("2ab1", "Local East Coordinate", DefaultAttribute.class); + public static final Characteristic LOCAL_NORTH_COORDINATE = new Characteristic("2ab0", "Local North Coordinate", DefaultAttribute.class); + public static final Characteristic LOCAL_TIME_INFORMATION = new Characteristic("2a0f", "Local Time Information", DefaultAttribute.class); + public static final Characteristic LOCATION_AND_SPEED = new Characteristic("2a67", "Location and Speed Characteristic", DefaultAttribute.class); + public static final Characteristic LOCATION_NAME = new Characteristic("2ab5", "Location Name", DefaultAttribute.class); + public static final Characteristic MAGNETIC_DECLINATION = new Characteristic("2a2c", "Magnetic Declination", DefaultAttribute.class); + public static final Characteristic MANUFACTURER_NAME_STRING = new Characteristic("2a29", "Manufacturer Name String", ManufacturerNameString.class); + public static final Characteristic MAXIMUM_RECOMMENDED_HEART_RATE = new Characteristic("2a91", "Maximum Recommended Heart Rate", DefaultAttribute.class); + public static final Characteristic MEASUREMENT_INTERVAL = new Characteristic("2a21", "Measurement Interval", DefaultAttribute.class); + public static final Characteristic MODEL_NUMBER_STRING = new Characteristic("2a24", "Model Number String", ModelNumberString.class); + public static final Characteristic NAVIGATION = new Characteristic("2a68", "Navigation", DefaultAttribute.class); + public static final Characteristic NETWORK_AVAILABILITY = new Characteristic("2a3e", "Network Availability", DefaultAttribute.class); + public static final Characteristic NEW_ALERT = new Characteristic("2a46", "New Alert", DefaultAttribute.class); + public static final Characteristic OBJECT_ACTION_CONTROL_POINT = new Characteristic("2ac5", "Object Action Control Point", DefaultAttribute.class); + public static final Characteristic OBJECT_CHANGED = new Characteristic("2ac8", "Object Changed", DefaultAttribute.class); + public static final Characteristic OBJECT_FIRST_CREATED = new Characteristic("2ac1", "Object First-Created", DefaultAttribute.class); + public static final Characteristic OBJECT_ID = new Characteristic("2ac3", "Object ID", DefaultAttribute.class); + public static final Characteristic OBJECT_LAST_MODIFIED = new Characteristic("2ac2", "Object Last-Modified", DefaultAttribute.class); + public static final Characteristic OBJECT_LIST_CONTROL_POINT = new Characteristic("2ac6", "Object List Control Point", DefaultAttribute.class); + public static final Characteristic OBJECT_LIST_FILTER = new Characteristic("2ac7", "Object List Filter", DefaultAttribute.class); + public static final Characteristic OBJECT_NAME = new Characteristic("2abe", "Object Name", DefaultAttribute.class); + public static final Characteristic OBJECT_PROPERTIES = new Characteristic("2ac4", "Object Properties", DefaultAttribute.class); + public static final Characteristic OBJECT_SIZE = new Characteristic("2ac0", "Object Size", DefaultAttribute.class); + public static final Characteristic OBJECT_TYPE = new Characteristic("2abf", "Object Type", DefaultAttribute.class); + public static final Characteristic OTS_FEATURE = new Characteristic("2abd", "OTS Feature", DefaultAttribute.class); + public static final Characteristic PERIPHERAL_PREFERRED_CONNECTION_PARAMETERS = new Characteristic("2a04", "Peripheral Preferred Connection Parameters", DefaultAttribute.class); + public static final Characteristic PERIPHERAL_PRIVACY_FLAG = new Characteristic("2a02", "Peripheral Privacy Flag", DefaultAttribute.class); + public static final Characteristic PLX_CONTINUOUS_MEASUREMENT = new Characteristic("2a5f", "PLX Continuous Measurement Characteristic", DefaultAttribute.class); + public static final Characteristic PLX_FEATURES = new Characteristic("2a60", "PLX Features", DefaultAttribute.class); + public static final Characteristic PLX_SPOT_CHECK_MEASUREMENT = new Characteristic("2a5e", "PLX Spot-Check Measurement", DefaultAttribute.class); + public static final Characteristic PNP_ID = new Characteristic("2a50", "PnP ID", DefaultAttribute.class); + public static final Characteristic POLLEN_CONCENTRATION = new Characteristic("2a75", "Pollen Concentration", DefaultAttribute.class); + public static final Characteristic POSITION_2D = new Characteristic("2a2f", "Position 2D", DefaultAttribute.class); + public static final Characteristic POSITION_3D = new Characteristic("2a30", "Position 3D", DefaultAttribute.class); + public static final Characteristic POSITION_QUALITY = new Characteristic("2a69", "Position Quality", DefaultAttribute.class); + public static final Characteristic PRESSURE = new Characteristic("2a6d", "Pressure", DefaultAttribute.class); + public static final Characteristic PROTOCOL_MODE = new Characteristic("2a4e", "Protocol Mode", DefaultAttribute.class); + public static final Characteristic PULSE_OXIMETRY_CONTROL_POINT = new Characteristic("2a62", "Pulse Oximetry Control Point", DefaultAttribute.class); + public static final Characteristic RAINFALL = new Characteristic("2a78", "Rainfall", DefaultAttribute.class); + public static final Characteristic RECONNECTION_ADDRESS = new Characteristic("2a03", "Reconnection Address", DefaultAttribute.class); + public static final Characteristic RECORD_ACCESS_CONTROL_POINT = new Characteristic("2a52", "Record Access Control Point", DefaultAttribute.class); + public static final Characteristic REFERENCE_TIME_INFORMATION = new Characteristic("2a14", "Reference Time Information", DefaultAttribute.class); + public static final Characteristic REMOVABLE = new Characteristic("2a3a", "Removable", DefaultAttribute.class); + public static final Characteristic REPORT = new Characteristic("2a4d", "Report", DefaultAttribute.class); + public static final Characteristic REPORT_MAP = new Characteristic("2a4b", "Report Map", DefaultAttribute.class); + public static final Characteristic RESOLVABLE_PRIVATE_ADDRESS_ONLY = new Characteristic("2ac9", "Resolvable Private Address Only", DefaultAttribute.class); + public static final Characteristic RESTING_HEART_RATE = new Characteristic("2a92", "Resting Heart Rate", DefaultAttribute.class); + public static final Characteristic RINGER_CONTROL_POINT = new Characteristic("2a40", "Ringer Control point", DefaultAttribute.class); + public static final Characteristic RINGER_SETTING = new Characteristic("2a41", "Ringer Setting", DefaultAttribute.class); + public static final Characteristic ROWER_DATA = new Characteristic("2ad1", "Rower Data", DefaultAttribute.class); + public static final Characteristic RSC_FEATURE = new Characteristic("2a54", "RSC Feature", DefaultAttribute.class); + public static final Characteristic RSC_MEASUREMENT = new Characteristic("2a53", "RSC Measurement", DefaultAttribute.class); + public static final Characteristic SC_CONTROL_POINT = new Characteristic("2a55", "SC Control Point", DefaultAttribute.class); + public static final Characteristic SCAN_INTERVAL_WINDOW = new Characteristic("2a4f", "Scan Interval Window", DefaultAttribute.class); + public static final Characteristic SCAN_REFRESH = new Characteristic("2a31", "Scan Refresh", DefaultAttribute.class); + public static final Characteristic SCIENTIFIC_TEMPERATURE_CELSIUS = new Characteristic("2a3c", "Scientific Temperature Celsius", DefaultAttribute.class); + public static final Characteristic SECONDARY_TIME_ZONE = new Characteristic("2a10", "Secondary Time Zone", DefaultAttribute.class); + public static final Characteristic SENSOR_LOCATION = new Characteristic("2a5d", "Sensor Location", DefaultAttribute.class); + public static final Characteristic SERIAL_NUMBER_STRING = new Characteristic("2a25", "Serial Number String", SerialNumberString.class); + public static final Characteristic SERVICE_CHANGED = new Characteristic("2a05", "Service Changed", DefaultAttribute.class); + public static final Characteristic SERVICE_REQUIRED = new Characteristic("2a3b", "Service Required", DefaultAttribute.class); + public static final Characteristic SOFTWARE_REVISION_STRING = new Characteristic("2a28", "Software Revision String", DefaultAttribute.class); + public static final Characteristic SPORT_TYPE_FOR_AEROBIC_AND_ANAEROBIC_THRESHOLDS = new Characteristic("2a93", "Sport Type for Aerobic and Anaerobic Thresholds", DefaultAttribute.class); + public static final Characteristic STAIR_CLIMBER_DATA = new Characteristic("2ad0", "Stair Climber Data", DefaultAttribute.class); + public static final Characteristic STEP_CLIMBER_DATA = new Characteristic("2acf", "Step Climber Data", DefaultAttribute.class); + public static final Characteristic STRING_ = new Characteristic("2a3d", "String", DefaultAttribute.class); + public static final Characteristic SUPPORTED_HEART_RATE_RANGE = new Characteristic("2ad7", "Supported Heart Rate Range", DefaultAttribute.class); + public static final Characteristic SUPPORTED_INCLINATION_RANGE = new Characteristic("2ad5", "Supported Inclination Range", DefaultAttribute.class); + public static final Characteristic SUPPORTED_NEW_ALERT_CATEGORY = new Characteristic("2a47", "Supported New Alert Category", DefaultAttribute.class); + public static final Characteristic SUPPORTED_POWER_RANGE = new Characteristic("2ad8", "Supported Power Range", DefaultAttribute.class); + public static final Characteristic SUPPORTED_RESISTANCE_LEVEL_RANGE = new Characteristic("2ad6", "Supported Resistance Level Range", DefaultAttribute.class); + public static final Characteristic SUPPORTED_SPEED_RANGE = new Characteristic("2ad4", "Supported Speed Range", DefaultAttribute.class); + public static final Characteristic SUPPORTED_UNREAD_ALERT_CATEGORY = new Characteristic("2a48", "Supported Unread Alert Category", DefaultAttribute.class); + public static final Characteristic SYSTEM_ID = new Characteristic("2a23", "System ID", DefaultAttribute.class); + public static final Characteristic TDS_CONTROL_POINT = new Characteristic("2abc", "TDS Control Point", DefaultAttribute.class); + public static final Characteristic TEMPERATURE = new Characteristic("2a6e", "Temperature", DefaultAttribute.class); + public static final Characteristic TEMPERATURE_CELSIUS = new Characteristic("2a1f", "Temperature Celsius", DefaultAttribute.class); + public static final Characteristic TEMPERATURE_FAHRENHEIT = new Characteristic("2a20", "Temperature Fahrenheit", DefaultAttribute.class); + public static final Characteristic TEMPERATURE_MEASUREMENT = new Characteristic("2a1c", "Temperature Measurement", DefaultAttribute.class); + public static final Characteristic TEMPERATURE_TYPE = new Characteristic("2a1d", "Temperature Type", DefaultAttribute.class); + public static final Characteristic THREE_ZONE_HEART_RATE_LIMITS = new Characteristic("2a94", "Three Zone Heart Rate Limits", DefaultAttribute.class); + public static final Characteristic TIME_ACCURACY = new Characteristic("2a12", "Time Accuracy", DefaultAttribute.class); + public static final Characteristic TIME_BROADCAST = new Characteristic("2a15", "Time Broadcast", DefaultAttribute.class); + public static final Characteristic TIME_SOURCE = new Characteristic("2a13", "Time Source", DefaultAttribute.class); + public static final Characteristic TIME_UPDATE_CONTROL_POINT = new Characteristic("2a16", "Time Update Control Point", DefaultAttribute.class); + public static final Characteristic TIME_UPDATE_STATE = new Characteristic("2a17", "Time Update State", DefaultAttribute.class); + public static final Characteristic TIME_WITH_DST = new Characteristic("2a11", "Time with DST", DefaultAttribute.class); + public static final Characteristic TIME_ZONE = new Characteristic("2a0e", "Time Zone", DefaultAttribute.class); + public static final Characteristic TRAINING_STATUS = new Characteristic("2ad3", "Training Status", DefaultAttribute.class); + public static final Characteristic TREADMILL_DATA = new Characteristic("2acd", "Treadmill Data", DefaultAttribute.class); + public static final Characteristic TRUE_WIND_DIRECTION = new Characteristic("2a71", "True Wind Direction", DefaultAttribute.class); + public static final Characteristic TRUE_WIND_SPEED = new Characteristic("2a70", "True Wind Speed", DefaultAttribute.class); + public static final Characteristic TWO_ZONE_HEART_RATE_LIMIT = new Characteristic("2a95", "Two Zone Heart Rate Limit", DefaultAttribute.class); + public static final Characteristic TX_POWER_LEVEL = new Characteristic("2a07", "Tx Power Level", DefaultAttribute.class); + public static final Characteristic UNCERTAINTY = new Characteristic("2ab4", "Uncertainty", DefaultAttribute.class); + public static final Characteristic UNREAD_ALERT_STATUS = new Characteristic("2a45", "Unread Alert Status", DefaultAttribute.class); + public static final Characteristic URI = new Characteristic("2ab6", "URI", DefaultAttribute.class); + public static final Characteristic USER_CONTROL_POINT = new Characteristic("2a9f", "User Control Point", DefaultAttribute.class); + public static final Characteristic USER_INDEX = new Characteristic("2a9a", "User Index", DefaultAttribute.class); + public static final Characteristic UV_INDEX = new Characteristic("2a76", "UV Index", DefaultAttribute.class); + public static final Characteristic VO2_MAX = new Characteristic("2a96", "VO2 Max", DefaultAttribute.class); + public static final Characteristic WAIST_CIRCUMFERENCE = new Characteristic("2a97", "Waist Circumference", DefaultAttribute.class); + public static final Characteristic WEIGHT = new Characteristic("2a98", "Weight", Weight.class); + public static final Characteristic WEIGHT_MEASUREMENT = new Characteristic("2a9d", "Weight Measurement", DefaultAttribute.class); + public static final Characteristic WEIGHT_SCALE_FEATURE = new Characteristic("2a9e", "Weight Scale Feature", DefaultAttribute.class); + public static final Characteristic WIND_CHILL = new Characteristic("2a79", "Wind Chill", DefaultAttribute.class); + + private static UuidObjectMap> characteristics = new UuidObjectMap>(); + + static + { + characteristics.put(LONGITUDE); + characteristics.put(MAGNETIC_FLUX_DENSITY_2D); + characteristics.put(MAGNETIC_FLUX_DENSITY_3D); + characteristics.put(AEROBIC_HEART_RATE_LOWER_LIMIT); + characteristics.put(AEROBIC_HEART_RATE_UPPER_LIMIT); + characteristics.put(AEROBIC_THRESHOLD); + characteristics.put(AGE); + characteristics.put(AGGREGATE); + characteristics.put(ALERT_CATEGORY_ID); + characteristics.put(ALERT_CATEGORY_ID_BIT_MASK); + characteristics.put(ALERT_LEVEL); + characteristics.put(ALERT_NOTIFICATION_CONTROL_POINT); + characteristics.put(ALERT_STATUS); + characteristics.put(ALTITUDE); + characteristics.put(ANAEROBIC_HEART_RATE_LOWER_LIMIT); + characteristics.put(ANAEROBIC_HEART_RATE_UPPER_LIMIT); + characteristics.put(ANAEROBIC_THRESHOLD); + characteristics.put(ANALOG); + characteristics.put(ANALOG_OUTPUT); + characteristics.put(APPARENT_WIND_DIRECTION); + characteristics.put(APPARENT_WIND_SPEED); + characteristics.put(APPEARANCE); + characteristics.put(BAROMETRIC_PRESSURE_TREND); + characteristics.put(BATTERY_LEVEL); + characteristics.put(BATTERY_LEVEL_STATE); + characteristics.put(BATTERY_POWER_STATE); + characteristics.put(BLOOD_PRESSURE_FEATURE); + characteristics.put(BLOOD_PRESSURE_MEASUREMENT); + characteristics.put(BODY_COMPOSITION_FEATURE); + characteristics.put(BODY_COMPOSITION_MEASUREMENT); + characteristics.put(BODY_SENSOR_LOCATION); + characteristics.put(BOND_MANAGEMENT_CONTROL_POINT); + characteristics.put(BOND_MANAGEMENT_FEATURE); + characteristics.put(BOOT_KEYBOARD_INPUT_REPORT); + characteristics.put(BOOT_KEYBOARD_OUTPUT_REPORT); + characteristics.put(BOOT_MOUSE_INPUT_REPORT); + characteristics.put(CGM_FEATURE); + characteristics.put(CGM_MEASUREMENT); + characteristics.put(CGM_SESSION_RUN_TIME); + characteristics.put(CGM_SESSION_START_TIME); + characteristics.put(CGM_SPECIFIC_OPS_CONTROL_POINT); + characteristics.put(CGM_STATUS); + characteristics.put(CROSS_TRAINER_DATA); + characteristics.put(CSC_FEATURE); + characteristics.put(CSC_MEASUREMENT); + characteristics.put(CURRENT_TIME); + characteristics.put(CYCLING_POWER_CONTROL_POINT); + characteristics.put(CYCLING_POWER_FEATURE); + characteristics.put(CYCLING_POWER_MEASUREMENT); + characteristics.put(CYCLING_POWER_VECTOR); + characteristics.put(DATABASE_CHANGE_INCREMENT); + characteristics.put(DATE_OF_BIRTH); + characteristics.put(DATE_OF_THRESHOLD_ASSESSMENT); + characteristics.put(DATE_TIME); + characteristics.put(DAY_DATE_TIME); + characteristics.put(DAY_OF_WEEK); + characteristics.put(DESCRIPTOR_VALUE_CHANGED); + characteristics.put(DEVICE_NAME); + characteristics.put(DEW_POINT); + characteristics.put(DIGITAL); + characteristics.put(DIGITAL_OUTPUT); + characteristics.put(DST_OFFSET); + characteristics.put(ELEVATION); + characteristics.put(EMAIL_ADDRESS); + characteristics.put(EXACT_TIME_100); + characteristics.put(EXACT_TIME_256); + characteristics.put(FAT_BURN_HEART_RATE_LOWER_LIMIT); + characteristics.put(FAT_BURN_HEART_RATE_UPPER_LIMIT); + characteristics.put(FIRMWARE_REVISION_STRING); + characteristics.put(FIRST_NAME); + characteristics.put(FITNESS_MACHINE_CONTROL_POINT); + characteristics.put(FITNESS_MACHINE_FEATURE); + characteristics.put(FITNESS_MACHINE_STATUS); + characteristics.put(FIVE_ZONE_HEART_RATE_LIMITS); + characteristics.put(FLOOR_NUMBER); + characteristics.put(GENDER); + characteristics.put(GLUCOSE_FEATURE); + characteristics.put(GLUCOSE_MEASUREMENT); + characteristics.put(GLUCOSE_MEASUREMENT_CONTEXT); + characteristics.put(GUST_FACTOR); + characteristics.put(HARDWARE_REVISION_STRING); + characteristics.put(HEART_RATE_CONTROL_POINT); + characteristics.put(HEART_RATE_MAX); + characteristics.put(HEART_RATE_MEASUREMENT); + characteristics.put(HEAT_INDEX); + characteristics.put(HEIGHT); + characteristics.put(HID_CONTROL_POINT); + characteristics.put(HID_INFORMATION); + characteristics.put(HIP_CIRCUMFERENCE); + characteristics.put(HTTP_CONTROL_POINT); + characteristics.put(HTTP_ENTITY_BODY); + characteristics.put(HTTP_HEADERS); + characteristics.put(HTTP_STATUS_CODE); + characteristics.put(HTTPS_SECURITY); + characteristics.put(HUMIDITY); + characteristics.put(IEEE_11073_20601_REGULATORY_CERTIFICATION_DATA_LIST); + characteristics.put(INDOOR_BIKE_DATA); + characteristics.put(INDOOR_POSITIONING_CONFIGURATION); + characteristics.put(INTERMEDIATE_CUFF_PRESSURE); + characteristics.put(INTERMEDIATE_TEMPERATURE); + characteristics.put(IRRADIANCE); + characteristics.put(LANGUAGE); + characteristics.put(LAST_NAME); + characteristics.put(LATITUDE); + characteristics.put(LN_CONTROL_POINT); + characteristics.put(LN_FEATURE); + characteristics.put(LOCAL_EAST_COORDINATE); + characteristics.put(LOCAL_NORTH_COORDINATE); + characteristics.put(LOCAL_TIME_INFORMATION); + characteristics.put(LOCATION_AND_SPEED); + characteristics.put(LOCATION_NAME); + characteristics.put(MAGNETIC_DECLINATION); + characteristics.put(MANUFACTURER_NAME_STRING); + characteristics.put(MAXIMUM_RECOMMENDED_HEART_RATE); + characteristics.put(MEASUREMENT_INTERVAL); + characteristics.put(MODEL_NUMBER_STRING); + characteristics.put(NAVIGATION); + characteristics.put(NETWORK_AVAILABILITY); + characteristics.put(NEW_ALERT); + characteristics.put(OBJECT_ACTION_CONTROL_POINT); + characteristics.put(OBJECT_CHANGED); + characteristics.put(OBJECT_FIRST_CREATED); + characteristics.put(OBJECT_ID); + characteristics.put(OBJECT_LAST_MODIFIED); + characteristics.put(OBJECT_LIST_CONTROL_POINT); + characteristics.put(OBJECT_LIST_FILTER); + characteristics.put(OBJECT_NAME); + characteristics.put(OBJECT_PROPERTIES); + characteristics.put(OBJECT_SIZE); + characteristics.put(OBJECT_TYPE); + characteristics.put(OTS_FEATURE); + characteristics.put(PERIPHERAL_PREFERRED_CONNECTION_PARAMETERS); + characteristics.put(PERIPHERAL_PRIVACY_FLAG); + characteristics.put(PLX_CONTINUOUS_MEASUREMENT); + characteristics.put(PLX_FEATURES); + characteristics.put(PLX_SPOT_CHECK_MEASUREMENT); + characteristics.put(PNP_ID); + characteristics.put(POLLEN_CONCENTRATION); + characteristics.put(POSITION_2D); + characteristics.put(POSITION_3D); + characteristics.put(POSITION_QUALITY); + characteristics.put(PRESSURE); + characteristics.put(PROTOCOL_MODE); + characteristics.put(PULSE_OXIMETRY_CONTROL_POINT); + characteristics.put(RAINFALL); + characteristics.put(RECONNECTION_ADDRESS); + characteristics.put(RECORD_ACCESS_CONTROL_POINT); + characteristics.put(REFERENCE_TIME_INFORMATION); + characteristics.put(REMOVABLE); + characteristics.put(REPORT); + characteristics.put(REPORT_MAP); + characteristics.put(RESOLVABLE_PRIVATE_ADDRESS_ONLY); + characteristics.put(RESTING_HEART_RATE); + characteristics.put(RINGER_CONTROL_POINT); + characteristics.put(RINGER_SETTING); + characteristics.put(ROWER_DATA); + characteristics.put(RSC_FEATURE); + characteristics.put(RSC_MEASUREMENT); + characteristics.put(SC_CONTROL_POINT); + characteristics.put(SCAN_INTERVAL_WINDOW); + characteristics.put(SCAN_REFRESH); + characteristics.put(SCIENTIFIC_TEMPERATURE_CELSIUS); + characteristics.put(SECONDARY_TIME_ZONE); + characteristics.put(SENSOR_LOCATION); + characteristics.put(SERIAL_NUMBER_STRING); + characteristics.put(SERVICE_CHANGED); + characteristics.put(SERVICE_REQUIRED); + characteristics.put(SOFTWARE_REVISION_STRING); + characteristics.put(SPORT_TYPE_FOR_AEROBIC_AND_ANAEROBIC_THRESHOLDS); + characteristics.put(STAIR_CLIMBER_DATA); + characteristics.put(STEP_CLIMBER_DATA); + characteristics.put(STRING_); + characteristics.put(SUPPORTED_HEART_RATE_RANGE); + characteristics.put(SUPPORTED_INCLINATION_RANGE); + characteristics.put(SUPPORTED_NEW_ALERT_CATEGORY); + characteristics.put(SUPPORTED_POWER_RANGE); + characteristics.put(SUPPORTED_RESISTANCE_LEVEL_RANGE); + characteristics.put(SUPPORTED_SPEED_RANGE); + characteristics.put(SUPPORTED_UNREAD_ALERT_CATEGORY); + characteristics.put(SYSTEM_ID); + characteristics.put(TDS_CONTROL_POINT); + characteristics.put(TEMPERATURE); + characteristics.put(TEMPERATURE_CELSIUS); + characteristics.put(TEMPERATURE_FAHRENHEIT); + characteristics.put(TEMPERATURE_MEASUREMENT); + characteristics.put(TEMPERATURE_TYPE); + characteristics.put(THREE_ZONE_HEART_RATE_LIMITS); + characteristics.put(TIME_ACCURACY); + characteristics.put(TIME_BROADCAST); + characteristics.put(TIME_SOURCE); + characteristics.put(TIME_UPDATE_CONTROL_POINT); + characteristics.put(TIME_UPDATE_STATE); + characteristics.put(TIME_WITH_DST); + characteristics.put(TIME_ZONE); + characteristics.put(TRAINING_STATUS); + characteristics.put(TREADMILL_DATA); + characteristics.put(TRUE_WIND_DIRECTION); + characteristics.put(TRUE_WIND_SPEED); + characteristics.put(TWO_ZONE_HEART_RATE_LIMIT); + characteristics.put(TX_POWER_LEVEL); + characteristics.put(UNCERTAINTY); + characteristics.put(UNREAD_ALERT_STATUS); + characteristics.put(URI); + characteristics.put(USER_CONTROL_POINT); + characteristics.put(USER_INDEX); + characteristics.put(UV_INDEX); + characteristics.put(VO2_MAX); + characteristics.put(WAIST_CIRCUMFERENCE); + characteristics.put(WEIGHT); + characteristics.put(WEIGHT_MEASUREMENT); + characteristics.put(WEIGHT_SCALE_FEATURE); + characteristics.put(WIND_CHILL); + } + + /** + * Get all Characteristics. + * + * @return all available Characteristics + */ + public static Collection> getCharacteristics() + { + return characteristics.getValues(); + } + + /** + * Looks up the characteristic for the given UUID. If the UUID is not found, a lookup in the smartgattlib is performed. + * + * @param uuid the UUID to look for + * @return the corresponding characteristic or the DEFAULT characteristic of smartgattlib if UUID is not found + */ + public static Characteristic lookup(UUID uuid) + { + Characteristic result = characteristics.get(uuid); + return result == null ? DEFAULT : result; + } + +} diff --git a/src-gen/main/java/com/movisens/smartgattlib/Services.java b/src-gen/main/java/com/movisens/smartgattlib/Services.java new file mode 100644 index 0000000..5684d4e --- /dev/null +++ b/src-gen/main/java/com/movisens/smartgattlib/Services.java @@ -0,0 +1,106 @@ +package com.movisens.smartgattlib; + +import java.util.UUID; + +import com.movisens.smartgattlib.helper.Service; +import com.movisens.smartgattlib.helper.UuidObjectMap; + +public class Services +{ + + public static final Service DEFAULT = new Service("0000", "Default Service"); + public static final Service ALERT_NOTIFICATION = new Service("1811", "Alert Notification Service"); + public static final Service AUTOMATION_IO = new Service("1815", "Automation IO"); + public static final Service BATTERY_SERVICE = new Service("180f", "Battery Service"); + public static final Service BLOOD_PRESSURE = new Service("1810", "Blood Pressure"); + public static final Service BODY_COMPOSITION = new Service("181b", "Body Composition"); + public static final Service BOND_MANAGEMENT = new Service("181e", "Bond Management Service"); + public static final Service CONTINUOUS_GLUCOSE_MONITORING = new Service("181f", "Continuous Glucose Monitoring"); + public static final Service CURRENT_TIME = new Service("1805", "Current Time Service"); + public static final Service CYCLING_POWER = new Service("1818", "Cycling Power"); + public static final Service CYCLING_SPEED_AND_CADENCE = new Service("1816", "Cycling Speed and Cadence"); + public static final Service DEVICE_INFORMATION = new Service("180a", "Device Information"); + public static final Service ENVIRONMENTAL_SENSING = new Service("181a", "Environmental Sensing"); + public static final Service FITNESS_MACHINE = new Service("1826", "Fitness Machine"); + public static final Service GENERIC_ACCESS = new Service("1800", " Generic Access"); + public static final Service GENERIC_ATTRIBUTE = new Service("1801", "Generic Attribute"); + public static final Service GLUCOSE = new Service("1808", "Glucose"); + public static final Service HEALTH_THERMOMETER = new Service("1809", "Health Thermometer"); + public static final Service HEART_RATE = new Service("180d", "Heart Rate"); + public static final Service HTTP_PROXY = new Service("1823", "HTTP Proxy"); + public static final Service HUMAN_INTERFACE_DEVICE = new Service("1812", "Human Interface Device"); + public static final Service IMMEDIATE_ALERT = new Service("1802", "Immediate Alert"); + public static final Service INDOOR_POSITIONING = new Service("1821", "Indoor Positioning"); + public static final Service INTERNET_PROTOCOL_SUPPORT = new Service("1820", "Internet Protocol Support Service"); + public static final Service LINK_LOSS = new Service("1803", "Link Loss"); + public static final Service LOCATION_AND_NAVIGATION = new Service("1819", "Location and Navigation"); + public static final Service MESH_PROVISIONING = new Service("1827", "Mesh Provisioning Service"); + public static final Service MESH_PROXY = new Service("1828", "Mesh Proxy Service"); + public static final Service NEXT_DST_CHANGE = new Service("1807", "Next DST Change Service"); + public static final Service OBJECT_TRANSFER = new Service("1825", "Object Transfer Service"); + public static final Service PHONE_ALERT_STATUS = new Service("180e", "Phone Alert Status Service"); + public static final Service PULSE_OXIMETER = new Service("1822", "Pulse Oximeter Service"); + public static final Service REFERENCE_TIME_UPDATE = new Service("1806", "Reference Time Update Service"); + public static final Service RUNNING_SPEED_AND_CADENCE = new Service("1814", "Running Speed and Cadence"); + public static final Service SCAN_PARAMETERS = new Service("1813", "Scan Parameters"); + public static final Service TRANSPORT_DISCOVERY = new Service("1824", "Transport Discovery"); + public static final Service TX_POWER = new Service("1804", "Tx Power"); + public static final Service USER_DATA = new Service("181c", "User Data"); + public static final Service WEIGHT_SCALE = new Service("181d", "Weight Scale"); + + private static UuidObjectMap services = new UuidObjectMap(); + + static + { + services.put(ALERT_NOTIFICATION); + services.put(AUTOMATION_IO); + services.put(BATTERY_SERVICE); + services.put(BLOOD_PRESSURE); + services.put(BODY_COMPOSITION); + services.put(BOND_MANAGEMENT); + services.put(CONTINUOUS_GLUCOSE_MONITORING); + services.put(CURRENT_TIME); + services.put(CYCLING_POWER); + services.put(CYCLING_SPEED_AND_CADENCE); + services.put(DEVICE_INFORMATION); + services.put(ENVIRONMENTAL_SENSING); + services.put(FITNESS_MACHINE); + services.put(GENERIC_ACCESS); + services.put(GENERIC_ATTRIBUTE); + services.put(GLUCOSE); + services.put(HEALTH_THERMOMETER); + services.put(HEART_RATE); + services.put(HTTP_PROXY); + services.put(HUMAN_INTERFACE_DEVICE); + services.put(IMMEDIATE_ALERT); + services.put(INDOOR_POSITIONING); + services.put(INTERNET_PROTOCOL_SUPPORT); + services.put(LINK_LOSS); + services.put(LOCATION_AND_NAVIGATION); + services.put(MESH_PROVISIONING); + services.put(MESH_PROXY); + services.put(NEXT_DST_CHANGE); + services.put(OBJECT_TRANSFER); + services.put(PHONE_ALERT_STATUS); + services.put(PULSE_OXIMETER); + services.put(REFERENCE_TIME_UPDATE); + services.put(RUNNING_SPEED_AND_CADENCE); + services.put(SCAN_PARAMETERS); + services.put(TRANSPORT_DISCOVERY); + services.put(TX_POWER); + services.put(USER_DATA); + services.put(WEIGHT_SCALE); + } + + /** + * Looks up the service for the given UUID. If the UUID is not found, a lookup in the smartgattlib is performed. + * + * @param uuid the UUID to look for + * @return the corresponding service or the DEFAULT service of smartgattlib if UUID is not found + */ + public static Service lookup(UUID uuid) + { + Service result = services.get(uuid); + return result == null ? DEFAULT : result; + } +} diff --git a/src-gen/main/java/com/movisens/smartgattlib/attributes/Age.java b/src-gen/main/java/com/movisens/smartgattlib/attributes/Age.java new file mode 100644 index 0000000..2a6e2ef --- /dev/null +++ b/src-gen/main/java/com/movisens/smartgattlib/attributes/Age.java @@ -0,0 +1,51 @@ +package com.movisens.smartgattlib.attributes; + +import com.movisens.smartgattlib.Characteristics; +import com.movisens.smartgattlib.helper.AbstractReadWriteAttribute; +import com.movisens.smartgattlib.helper.Characteristic; +import com.movisens.smartgattlib.helper.GattByteBuffer; + +public class Age extends AbstractReadWriteAttribute +{ + + public static final Characteristic CHARACTERISTIC = Characteristics.AGE; + + private Short age; + + public Short getAge() + { + return age; + } + + public String getAgeUnit() + { + return ""; + } + + public Age(Short age) + { + this.age = age; + GattByteBuffer bb = GattByteBuffer.allocate(1); + bb.putUint8(age); + this.data = bb.array(); + } + + public Age(byte[] data) + { + this.data = data; + GattByteBuffer bb = GattByteBuffer.wrap(data); + age = bb.getUint8(); + } + + @Override + public Characteristic getCharacteristic() + { + return CHARACTERISTIC; + } + + @Override + public String toString() + { + return getAge().toString(); + } +} diff --git a/src-gen/main/java/com/movisens/smartgattlib/attributes/Appearance.java b/src-gen/main/java/com/movisens/smartgattlib/attributes/Appearance.java new file mode 100644 index 0000000..d3280d2 --- /dev/null +++ b/src-gen/main/java/com/movisens/smartgattlib/attributes/Appearance.java @@ -0,0 +1,44 @@ +package com.movisens.smartgattlib.attributes; + +import com.movisens.smartgattlib.Characteristics; +import com.movisens.smartgattlib.helper.AbstractReadAttribute; +import com.movisens.smartgattlib.helper.Characteristic; +import com.movisens.smartgattlib.helper.GattByteBuffer; +import com.movisens.smartgattlib.helper.PlainTextAttribute; + +public class Appearance extends AbstractReadAttribute implements PlainTextAttribute +{ + + public static final Characteristic CHARACTERISTIC = Characteristics.APPEARANCE; + + private Short category; + + public Short getCategory() + { + return category; + } + + public String getCategoryUnit() + { + return ""; + } + + public Appearance(byte[] data) + { + this.data = data; + GattByteBuffer bb = GattByteBuffer.wrap(data); + category = bb.getInt16(); + } + + @Override + public Characteristic getCharacteristic() + { + return CHARACTERISTIC; + } + + @Override + public String toString() + { + return getCategory().toString(); + } +} diff --git a/src-gen/main/java/com/movisens/smartgattlib/attributes/BatteryLevel.java b/src-gen/main/java/com/movisens/smartgattlib/attributes/BatteryLevel.java new file mode 100644 index 0000000..2d74b00 --- /dev/null +++ b/src-gen/main/java/com/movisens/smartgattlib/attributes/BatteryLevel.java @@ -0,0 +1,43 @@ +package com.movisens.smartgattlib.attributes; + +import com.movisens.smartgattlib.Characteristics; +import com.movisens.smartgattlib.helper.AbstractReadAttribute; +import com.movisens.smartgattlib.helper.Characteristic; +import com.movisens.smartgattlib.helper.GattByteBuffer; + +public class BatteryLevel extends AbstractReadAttribute +{ + + public static final Characteristic CHARACTERISTIC = Characteristics.BATTERY_LEVEL; + + private Double level; + + public Double getLevel() + { + return level; + } + + public String getLevelUnit() + { + return "%"; + } + + public BatteryLevel(byte[] data) + { + this.data = data; + GattByteBuffer bb = GattByteBuffer.wrap(data); + level = new Double(bb.getUint8()); + } + + @Override + public Characteristic getCharacteristic() + { + return CHARACTERISTIC; + } + + @Override + public String toString() + { + return getLevel().toString() + getLevelUnit(); + } +} diff --git a/src-gen/main/java/com/movisens/smartgattlib/attributes/DateOfBirth.java b/src-gen/main/java/com/movisens/smartgattlib/attributes/DateOfBirth.java new file mode 100644 index 0000000..d67b979 --- /dev/null +++ b/src-gen/main/java/com/movisens/smartgattlib/attributes/DateOfBirth.java @@ -0,0 +1,79 @@ +package com.movisens.smartgattlib.attributes; + +import com.movisens.smartgattlib.Characteristics; +import com.movisens.smartgattlib.helper.AbstractReadWriteAttribute; +import com.movisens.smartgattlib.helper.Characteristic; +import com.movisens.smartgattlib.helper.GattByteBuffer; + +public class DateOfBirth extends AbstractReadWriteAttribute +{ + + public static final Characteristic CHARACTERISTIC = Characteristics.DATE_OF_BIRTH; + + private Integer year; + private Short month; + private Short day; + + public Integer getYear() + { + return year; + } + + public String getYearUnit() + { + return ""; + } + + public Short getMonth() + { + return month; + } + + public String getMonthUnit() + { + return ""; + } + + public Short getDay() + { + return day; + } + + public String getDayUnit() + { + return ""; + } + + public DateOfBirth(Integer year, Short month, Short day) + { + this.year = year; + this.month = month; + this.day = day; + GattByteBuffer bb = GattByteBuffer.allocate(4); + bb.putUint16(year); + bb.putUint8(month); + bb.putUint8(day); + this.data = bb.array(); + } + + public DateOfBirth(byte[] data) + { + this.data = data; + GattByteBuffer bb = GattByteBuffer.wrap(data); + year = bb.getUint16(); + month = bb.getUint8(); + day = bb.getUint8(); + } + + @Override + public Characteristic getCharacteristic() + { + return CHARACTERISTIC; + } + + @Override + public String toString() + { + return "year = " + getYear().toString() + ", " + "month = " + getMonth().toString() + ", " + "day = " + getDay().toString(); + } +} diff --git a/src-gen/main/java/com/movisens/smartgattlib/attributes/DeviceName.java b/src-gen/main/java/com/movisens/smartgattlib/attributes/DeviceName.java new file mode 100644 index 0000000..c7438c2 --- /dev/null +++ b/src-gen/main/java/com/movisens/smartgattlib/attributes/DeviceName.java @@ -0,0 +1,44 @@ +package com.movisens.smartgattlib.attributes; + +import com.movisens.smartgattlib.Characteristics; +import com.movisens.smartgattlib.helper.AbstractReadAttribute; +import com.movisens.smartgattlib.helper.Characteristic; +import com.movisens.smartgattlib.helper.GattByteBuffer; +import com.movisens.smartgattlib.helper.PlainTextAttribute; + +public class DeviceName extends AbstractReadAttribute implements PlainTextAttribute +{ + + public static final Characteristic CHARACTERISTIC = Characteristics.DEVICE_NAME; + + private String name; + + public String getName() + { + return name; + } + + public String getNameUnit() + { + return ""; + } + + public DeviceName(byte[] data) + { + this.data = data; + GattByteBuffer bb = GattByteBuffer.wrap(data); + name = bb.getString(); + } + + @Override + public Characteristic getCharacteristic() + { + return CHARACTERISTIC; + } + + @Override + public String toString() + { + return getName().toString(); + } +} diff --git a/src-gen/main/java/com/movisens/smartgattlib/attributes/EnumGender.java b/src-gen/main/java/com/movisens/smartgattlib/attributes/EnumGender.java new file mode 100644 index 0000000..649d95d --- /dev/null +++ b/src-gen/main/java/com/movisens/smartgattlib/attributes/EnumGender.java @@ -0,0 +1,49 @@ +package com.movisens.smartgattlib.attributes; + +public enum EnumGender +{ + MALE ((short)0, "Male"), + FEMALE ((short)1, "Female"), + UNSPECIFIED ((short)2, "Unspecified"), + INVALID ((short)3, "invalid"); + + private final short value; + private final String name; + + EnumGender(short value, String name) + { + this.value = value; + this.name = name; + } + + public short getValue() + { + return value; + } + + public String getName() + { + return name; + } + + public static EnumGender getByValue(short value) + { + switch (value) + { + case 0: + return EnumGender.MALE; + case 1: + return EnumGender.FEMALE; + case 2: + return EnumGender.UNSPECIFIED; + default: + return EnumGender.INVALID; + } + } + + @Override + public String toString() + { + return name; + } +} diff --git a/src-gen/main/java/com/movisens/smartgattlib/attributes/FirmwareRevisionString.java b/src-gen/main/java/com/movisens/smartgattlib/attributes/FirmwareRevisionString.java new file mode 100644 index 0000000..c063df0 --- /dev/null +++ b/src-gen/main/java/com/movisens/smartgattlib/attributes/FirmwareRevisionString.java @@ -0,0 +1,44 @@ +package com.movisens.smartgattlib.attributes; + +import com.movisens.smartgattlib.Characteristics; +import com.movisens.smartgattlib.helper.AbstractReadAttribute; +import com.movisens.smartgattlib.helper.Characteristic; +import com.movisens.smartgattlib.helper.GattByteBuffer; +import com.movisens.smartgattlib.helper.PlainTextAttribute; + +public class FirmwareRevisionString extends AbstractReadAttribute implements PlainTextAttribute +{ + + public static final Characteristic CHARACTERISTIC = Characteristics.FIRMWARE_REVISION_STRING; + + private String firmware_Revision; + + public String getFirmware_Revision() + { + return firmware_Revision; + } + + public String getFirmware_RevisionUnit() + { + return ""; + } + + public FirmwareRevisionString(byte[] data) + { + this.data = data; + GattByteBuffer bb = GattByteBuffer.wrap(data); + firmware_Revision = bb.getString(); + } + + @Override + public Characteristic getCharacteristic() + { + return CHARACTERISTIC; + } + + @Override + public String toString() + { + return getFirmware_Revision().toString(); + } +} diff --git a/src-gen/main/java/com/movisens/smartgattlib/attributes/Gender.java b/src-gen/main/java/com/movisens/smartgattlib/attributes/Gender.java new file mode 100644 index 0000000..f495c85 --- /dev/null +++ b/src-gen/main/java/com/movisens/smartgattlib/attributes/Gender.java @@ -0,0 +1,51 @@ +package com.movisens.smartgattlib.attributes; + +import com.movisens.smartgattlib.Characteristics; +import com.movisens.smartgattlib.helper.AbstractReadWriteAttribute; +import com.movisens.smartgattlib.helper.Characteristic; +import com.movisens.smartgattlib.helper.GattByteBuffer; + +public class Gender extends AbstractReadWriteAttribute +{ + + public static final Characteristic CHARACTERISTIC = Characteristics.GENDER; + + private EnumGender gender; + + public EnumGender getGender() + { + return gender; + } + + public String getGenderUnit() + { + return ""; + } + + public Gender(EnumGender gender) + { + this.gender = gender; + GattByteBuffer bb = GattByteBuffer.allocate(1); + bb.putUint8(gender.getValue()); + this.data = bb.array(); + } + + public Gender(byte[] data) + { + this.data = data; + GattByteBuffer bb = GattByteBuffer.wrap(data); + gender = EnumGender.getByValue(bb.getUint8()); + } + + @Override + public Characteristic getCharacteristic() + { + return CHARACTERISTIC; + } + + @Override + public String toString() + { + return getGender().toString(); + } +} diff --git a/src-gen/main/java/com/movisens/smartgattlib/attributes/Height.java b/src-gen/main/java/com/movisens/smartgattlib/attributes/Height.java new file mode 100644 index 0000000..96ea9bc --- /dev/null +++ b/src-gen/main/java/com/movisens/smartgattlib/attributes/Height.java @@ -0,0 +1,59 @@ +package com.movisens.smartgattlib.attributes; + +import com.movisens.smartgattlib.Characteristics; +import com.movisens.smartgattlib.helper.AbstractReadWriteAttribute; +import com.movisens.smartgattlib.helper.Characteristic; +import com.movisens.smartgattlib.helper.GattByteBuffer; + +public class Height extends AbstractReadWriteAttribute +{ + + public static final Characteristic CHARACTERISTIC = Characteristics.HEIGHT; + + private Double heigt; + + public Double getHeigt() + { + return heigt; + } + + public String getHeigtUnit() + { + return "m"; + } + + public Height(Double heigt) + { + if(heigt<0.0) + { + throw new RuntimeException("heigt out of range! Min value is 0.0"); + } + if(heigt>3.0) + { + throw new RuntimeException("heigt out of range! Max value is 3.0"); + } + this.heigt = heigt; + GattByteBuffer bb = GattByteBuffer.allocate(2); + bb.putUint16(new Long(Math.round(heigt / 0.01)).intValue()); + this.data = bb.array(); + } + + public Height(byte[] data) + { + this.data = data; + GattByteBuffer bb = GattByteBuffer.wrap(data); + heigt = ((double)bb.getUint16()) * 0.01; + } + + @Override + public Characteristic getCharacteristic() + { + return CHARACTERISTIC; + } + + @Override + public String toString() + { + return getHeigt().toString() + getHeigtUnit(); + } +} diff --git a/src-gen/main/java/com/movisens/smartgattlib/attributes/ManufacturerNameString.java b/src-gen/main/java/com/movisens/smartgattlib/attributes/ManufacturerNameString.java new file mode 100644 index 0000000..de92313 --- /dev/null +++ b/src-gen/main/java/com/movisens/smartgattlib/attributes/ManufacturerNameString.java @@ -0,0 +1,44 @@ +package com.movisens.smartgattlib.attributes; + +import com.movisens.smartgattlib.Characteristics; +import com.movisens.smartgattlib.helper.AbstractReadAttribute; +import com.movisens.smartgattlib.helper.Characteristic; +import com.movisens.smartgattlib.helper.GattByteBuffer; +import com.movisens.smartgattlib.helper.PlainTextAttribute; + +public class ManufacturerNameString extends AbstractReadAttribute implements PlainTextAttribute +{ + + public static final Characteristic CHARACTERISTIC = Characteristics.MANUFACTURER_NAME_STRING; + + private String manufacturer_Name; + + public String getManufacturer_Name() + { + return manufacturer_Name; + } + + public String getManufacturer_NameUnit() + { + return ""; + } + + public ManufacturerNameString(byte[] data) + { + this.data = data; + GattByteBuffer bb = GattByteBuffer.wrap(data); + manufacturer_Name = bb.getString(); + } + + @Override + public Characteristic getCharacteristic() + { + return CHARACTERISTIC; + } + + @Override + public String toString() + { + return getManufacturer_Name().toString(); + } +} diff --git a/src-gen/main/java/com/movisens/smartgattlib/attributes/ModelNumberString.java b/src-gen/main/java/com/movisens/smartgattlib/attributes/ModelNumberString.java new file mode 100644 index 0000000..671c0e0 --- /dev/null +++ b/src-gen/main/java/com/movisens/smartgattlib/attributes/ModelNumberString.java @@ -0,0 +1,44 @@ +package com.movisens.smartgattlib.attributes; + +import com.movisens.smartgattlib.Characteristics; +import com.movisens.smartgattlib.helper.AbstractReadAttribute; +import com.movisens.smartgattlib.helper.Characteristic; +import com.movisens.smartgattlib.helper.GattByteBuffer; +import com.movisens.smartgattlib.helper.PlainTextAttribute; + +public class ModelNumberString extends AbstractReadAttribute implements PlainTextAttribute +{ + + public static final Characteristic CHARACTERISTIC = Characteristics.MODEL_NUMBER_STRING; + + private String model_Number; + + public String getModel_Number() + { + return model_Number; + } + + public String getModel_NumberUnit() + { + return ""; + } + + public ModelNumberString(byte[] data) + { + this.data = data; + GattByteBuffer bb = GattByteBuffer.wrap(data); + model_Number = bb.getString(); + } + + @Override + public Characteristic getCharacteristic() + { + return CHARACTERISTIC; + } + + @Override + public String toString() + { + return getModel_Number().toString(); + } +} diff --git a/src-gen/main/java/com/movisens/smartgattlib/attributes/SerialNumberString.java b/src-gen/main/java/com/movisens/smartgattlib/attributes/SerialNumberString.java new file mode 100644 index 0000000..725563c --- /dev/null +++ b/src-gen/main/java/com/movisens/smartgattlib/attributes/SerialNumberString.java @@ -0,0 +1,44 @@ +package com.movisens.smartgattlib.attributes; + +import com.movisens.smartgattlib.Characteristics; +import com.movisens.smartgattlib.helper.AbstractReadAttribute; +import com.movisens.smartgattlib.helper.Characteristic; +import com.movisens.smartgattlib.helper.GattByteBuffer; +import com.movisens.smartgattlib.helper.PlainTextAttribute; + +public class SerialNumberString extends AbstractReadAttribute implements PlainTextAttribute +{ + + public static final Characteristic CHARACTERISTIC = Characteristics.SERIAL_NUMBER_STRING; + + private String serial_Number; + + public String getSerial_Number() + { + return serial_Number; + } + + public String getSerial_NumberUnit() + { + return ""; + } + + public SerialNumberString(byte[] data) + { + this.data = data; + GattByteBuffer bb = GattByteBuffer.wrap(data); + serial_Number = bb.getString(); + } + + @Override + public Characteristic getCharacteristic() + { + return CHARACTERISTIC; + } + + @Override + public String toString() + { + return getSerial_Number().toString(); + } +} diff --git a/src-gen/main/java/com/movisens/smartgattlib/attributes/Weight.java b/src-gen/main/java/com/movisens/smartgattlib/attributes/Weight.java new file mode 100644 index 0000000..0c8e4cf --- /dev/null +++ b/src-gen/main/java/com/movisens/smartgattlib/attributes/Weight.java @@ -0,0 +1,59 @@ +package com.movisens.smartgattlib.attributes; + +import com.movisens.smartgattlib.Characteristics; +import com.movisens.smartgattlib.helper.AbstractReadWriteAttribute; +import com.movisens.smartgattlib.helper.Characteristic; +import com.movisens.smartgattlib.helper.GattByteBuffer; + +public class Weight extends AbstractReadWriteAttribute +{ + + public static final Characteristic CHARACTERISTIC = Characteristics.WEIGHT; + + private Double weight; + + public Double getWeight() + { + return weight; + } + + public String getWeightUnit() + { + return "kg"; + } + + public Weight(Double weight) + { + if(weight<0.0) + { + throw new RuntimeException("weight out of range! Min value is 0.0"); + } + if(weight>327.68) + { + throw new RuntimeException("weight out of range! Max value is 327.68"); + } + this.weight = weight; + GattByteBuffer bb = GattByteBuffer.allocate(2); + bb.putUint16(new Long(Math.round(weight / 0.005)).intValue()); + this.data = bb.array(); + } + + public Weight(byte[] data) + { + this.data = data; + GattByteBuffer bb = GattByteBuffer.wrap(data); + weight = ((double)bb.getUint16()) * 0.005; + } + + @Override + public Characteristic getCharacteristic() + { + return CHARACTERISTIC; + } + + @Override + public String toString() + { + return getWeight().toString() + getWeightUnit(); + } +} diff --git a/src/main/java/com/movisens/smartgattlib/Characteristic.java b/src/main/java/com/movisens/smartgattlib/Characteristic.java deleted file mode 100644 index 60ca674..0000000 --- a/src/main/java/com/movisens/smartgattlib/Characteristic.java +++ /dev/null @@ -1,224 +0,0 @@ -package com.movisens.smartgattlib; - -import java.util.HashMap; -import java.util.UUID; - -public class Characteristic { - public static final UUID ALERT_CATEGORY_ID = new UUID((0x2A43L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID ALERT_CATEGORY_ID_BIT_MASK = new UUID((0x2A42L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID ALERT_LEVEL = new UUID((0x2A06L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID ALERT_NOTIFICATION_CONTROL_POINT = new UUID((0x2A44L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID ALERT_STATUS = new UUID((0x2A3FL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID APPEARANCE = new UUID((0x2A01L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID BATTERY_LEVEL = new UUID((0x2A19L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID BLOOD_PRESSURE_FEATURE = new UUID((0x2A49L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID BLOOD_PRESSURE_MEASUREMENT = new UUID((0x2A35L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID BODY_SENSOR_LOCATION = new UUID((0x2A38L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID BOOT_KEYOBARD_INPUT_REPORT = new UUID((0x2A22L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID BOOT_KEYOBARD_OUTPUT_REPORT = new UUID((0x2A32L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID BOOT_MOUSE_INPUT_REPORT = new UUID((0x2A33L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID CSC_FEATURE = new UUID((0x2A5CL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID CSC_MEASUREMENT = new UUID((0x2A5BL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID CURRENT_TIME = new UUID((0x2A2BL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID CYCLING_POWER_CONTROL_POINT = new UUID((0x2A66L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID CYCLING_POWER_FEATURE = new UUID((0x2A65L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID CYCLING_POWER_MEASUREMENT = new UUID((0x2A63L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID CYCLING_POWER_VECTOR = new UUID((0x2A64L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID DATE_TIME = new UUID((0x2A08L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID DAY_DATE_TIME = new UUID((0x2A0AL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID DAY_OF_WEEK = new UUID((0x2A09L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID DEVICE_NAME = new UUID((0x2A00L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID DST_OFFSET = new UUID((0x2A0DL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID EXACT_TIME_256 = new UUID((0x2A0CL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID FIRMWARE_REVISION_STRING = new UUID((0x2A26L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID GLUCOSE_FEATURE = new UUID((0x2A51L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID GLUCOSE_MEASUREMENT = new UUID((0x2A18L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID GLUCOSE_MEASUREMENT_CONTROL = new UUID((0x2A34L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID HARDWARE_REVISION_STRING = new UUID((0x2A27L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID HEART_RATE_CONTROL_POINT = new UUID((0x2A39L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID HEART_RATE_MEASUREMENT = new UUID((0x2A37L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID HID_CONTROL_POINT = new UUID((0x2A4CL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID HID_INFORMATION = new UUID((0x2A4AL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID IEEE11073_20601_REGULATORY_CERTIFICATION_DATA_LIST = new UUID((0x2A2AL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID INTERMEDIATE_CUFF_PRESSURE = new UUID((0x2A36L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID INTERMEDIATE_TEMPERATURE = new UUID((0x2A1EL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID LN_CONTROL_POINT = new UUID((0x2A6BL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID LN_FEATURE = new UUID((0x2A6AL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID LOCAL_TIME_INFORMATION = new UUID((0x2A0FL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID LOCATION_AND_SPEED = new UUID((0x2A67L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID MANUFACTURER_NAME_STRING = new UUID((0x2A29L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID MEASUREMENT_INTERVAL = new UUID((0x2A21L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID MODEL_NUMBER_STRING = new UUID((0x2A24L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID NAVIGATION = new UUID((0x2A68L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID NEW_ALERT = new UUID((0x2A46L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID PERIPERAL_PREFFERED_CONNECTION_PARAMETERS = new UUID((0x2A04L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID PERIPHERAL_PRIVACY_FLAG = new UUID((0x2A02L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID PN_PID = new UUID((0x2A50L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID POSITION_QUALITY = new UUID((0x2A69L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID PROTOCOL_MODE = new UUID((0x2A4EL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID RECONNECTION_ADDRESS = new UUID((0x2A03L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID RECORD_ACCESS_CONTROL_POINT = new UUID((0x2A52L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID REFERENCE_TIME_INFORMATION = new UUID((0x2A14L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID REPORT = new UUID((0x2A4DL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID REPORT_MAP = new UUID((0x2A4BL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID RINGER_CONTROL_POINT = new UUID((0x2A40L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID RINGER_SETTING = new UUID((0x2A41L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID RSC_FEATURE = new UUID((0x2A54L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID RSC_MEASUREMENT = new UUID((0x2A53L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID SC_CONTROL_POINT = new UUID((0x2A55L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID SCAN_INTERVAL_WINDOW = new UUID((0x2A4FL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID SCAN_REFRESH = new UUID((0x2A31L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID SENSOR_LOCATION = new UUID((0x2A5DL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID SERIAL_NUMBER_STRING = new UUID((0x2A25L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID SERVICE_CHANGED = new UUID((0x2A05L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID SOFTWARE_REVISION_STRING = new UUID((0x2A28L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID SUPPORTED_NEW_ALERT_CATEGORY = new UUID((0x2A47L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID SUPPORTED_UNREAD_ALERT_CATEGORY = new UUID((0x2A48L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID SYSTEM_ID = new UUID((0x2A23L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID TEMPERATURE_MEASUREMENT = new UUID((0x2A1CL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID TEMPERATURE_TYPE = new UUID((0x2A1DL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID TIME_ACCURACY = new UUID((0x2A12L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID TIME_SOURCE = new UUID((0x2A13L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID TIME_UPDATE_CONTROL_POINT = new UUID((0x2A16L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID TIME_UPDATE_STATE = new UUID((0x2A17L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID TIME_WITH_DST = new UUID((0x2A11L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID TIME_ZONE = new UUID((0x2A0EL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID TX_POWER_LEVEL = new UUID((0x2A07L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID UNREAD_ALERT_STATUS = new UUID((0x2A45L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID AGGREGATE_INPUT = new UUID((0x2A5AL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID ANALOG_INPUT = new UUID((0x2A58L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID ANALOG_OUTPUT = new UUID((0x2A59L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID DIGITAL_INPUT = new UUID((0x2A56L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID DIGITAL_OUTPUT = new UUID((0x2A57L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID EXACT_TIME_100 = new UUID((0x2A0BL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID NETWORK_AVAILABILITY = new UUID((0x2A3EL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID SCIENTIFIC_TEMPERATURE_IN_CELSIUS = new UUID((0x2A3CL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID SECONDARY_TIME_ZONE = new UUID((0x2A10L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID STRING = new UUID((0x2A3DL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID TEMPERATURE_IN_CELSIUS = new UUID((0x2A1FL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID TEMPERATURE_IN_FAHRENHEIT = new UUID((0x2A20L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID TIME_BROADCAST = new UUID((0x2A15L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID BATTERY_LEVEL_STATE = new UUID((0x2A1BL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID BATTERY_POWER_STATE = new UUID((0x2A1AL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID PULSE_OXIMETRY_CONTINUOUS_MEASUREMENT = new UUID((0x2A5FL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID PULSE_OXIMETRY_CONTROL_POINT = new UUID((0x2A62L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID PULSE_OXIMETRY_FEATURES = new UUID((0x2A61L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID PULSE_OXIMETRY_PULSATILE_EVENT = new UUID((0x2A60L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID PULSE_OXIMETRY_SPOT_CHECK_MEASUREMENT = new UUID((0x2A5EL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID RECORD_ACCESS_CONTROL_POINT_TESTVERSION = new UUID((0x2A52L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID REMOVABLE = new UUID((0x2A3AL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID SERVICE_REQUIRED = new UUID((0x2A3BL << 32) | 0x1000, GattUtils.leastSigBits); - - private static HashMap attributes = new HashMap(); - static { - attributes.put(ALERT_CATEGORY_ID, "Alert Category ID"); - attributes.put(ALERT_CATEGORY_ID_BIT_MASK, "Alert Category ID Bit Mask"); - attributes.put(ALERT_LEVEL, "Alert Level"); - attributes.put(ALERT_NOTIFICATION_CONTROL_POINT, "Alert Notification Control Point"); - attributes.put(ALERT_STATUS, "Alert Status"); - attributes.put(APPEARANCE, "Appearance"); - attributes.put(BATTERY_LEVEL, "Battery Level"); - attributes.put(BLOOD_PRESSURE_FEATURE, "Blood Pressure Feature"); - attributes.put(BLOOD_PRESSURE_MEASUREMENT, "Blood Pressure Measurement"); - attributes.put(BODY_SENSOR_LOCATION, "Body Sensor Location"); - attributes.put(BOOT_KEYOBARD_INPUT_REPORT, "Boot Keyboard Input Report"); - attributes.put(BOOT_KEYOBARD_OUTPUT_REPORT, "Boot Keyboard Output Report"); - attributes.put(BOOT_MOUSE_INPUT_REPORT, "Boot Mouse Input Report"); - attributes.put(CSC_FEATURE, "CSC Feature"); - attributes.put(CSC_MEASUREMENT, "CSC Measurement"); - attributes.put(CURRENT_TIME, "Current Time"); - attributes.put(CYCLING_POWER_CONTROL_POINT, "Cycling Power Control Point"); - attributes.put(CYCLING_POWER_FEATURE, "Cycling Power Feature"); - attributes.put(CYCLING_POWER_MEASUREMENT, "Cycling Power Measurement"); - attributes.put(CYCLING_POWER_VECTOR, "Cycling Power Vector"); - attributes.put(DATE_TIME, "Date Time"); - attributes.put(DAY_DATE_TIME, "Day Date Time"); - attributes.put(DAY_OF_WEEK, "Day of Week"); - attributes.put(DEVICE_NAME, "Device Name"); - attributes.put(DST_OFFSET, "DST Offset"); - attributes.put(EXACT_TIME_256, "Exact Time 256"); - attributes.put(FIRMWARE_REVISION_STRING, "Firmware Revision String"); - attributes.put(GLUCOSE_FEATURE, "Glucose Feature"); - attributes.put(GLUCOSE_MEASUREMENT, "Glucose Measurement"); - attributes.put(GLUCOSE_MEASUREMENT_CONTROL, "Glucose Measurement Context"); - attributes.put(HARDWARE_REVISION_STRING, "Hardware Revision String"); - attributes.put(HEART_RATE_CONTROL_POINT, "Heart Rate Control Point"); - attributes.put(HEART_RATE_MEASUREMENT, "Heart Rate Measurement"); - attributes.put(HID_CONTROL_POINT, "HID Control Point"); - attributes.put(HID_INFORMATION, "HID Information"); - attributes.put(IEEE11073_20601_REGULATORY_CERTIFICATION_DATA_LIST, "IEEE 11073-20601 Regulatory Certification Data List"); - attributes.put(INTERMEDIATE_CUFF_PRESSURE, "Intermediate Cuff Pressure"); - attributes.put(INTERMEDIATE_TEMPERATURE, "Intermediate Temperature"); - attributes.put(LN_CONTROL_POINT, "LN Control Point"); - attributes.put(LN_FEATURE, "LN Feature"); - attributes.put(LOCAL_TIME_INFORMATION, "Local Time Information"); - attributes.put(LOCATION_AND_SPEED, "Location and Speed"); - attributes.put(MANUFACTURER_NAME_STRING, "Manufacturer Name String"); - attributes.put(MEASUREMENT_INTERVAL, "Measurement Interval"); - attributes.put(MODEL_NUMBER_STRING, "Model Number String"); - attributes.put(NAVIGATION, "Navigation"); - attributes.put(NEW_ALERT, "New Alert"); - attributes.put(PERIPERAL_PREFFERED_CONNECTION_PARAMETERS, "Peripheral Preferred Connection Parameters"); - attributes.put(PERIPHERAL_PRIVACY_FLAG, "Peripheral Privacy Flag"); - attributes.put(PN_PID, "PnP ID"); - attributes.put(POSITION_QUALITY, "Position Quality"); - attributes.put(PROTOCOL_MODE, "Protocol Mode"); - attributes.put(RECONNECTION_ADDRESS, "Reconnection Address"); - attributes.put(RECORD_ACCESS_CONTROL_POINT, "Record Access Control Point"); - attributes.put(REFERENCE_TIME_INFORMATION, "Reference Time Information"); - attributes.put(REPORT, "Report"); - attributes.put(REPORT_MAP, "Report Map"); - attributes.put(RINGER_CONTROL_POINT, "Ringer Control Point"); - attributes.put(RINGER_SETTING, "Ringer Setting"); - attributes.put(RSC_FEATURE, "RSC Feature"); - attributes.put(RSC_MEASUREMENT, "RSC Measurement"); - attributes.put(SC_CONTROL_POINT, "SC Control Point"); - attributes.put(SCAN_INTERVAL_WINDOW, "Scan Interval Window"); - attributes.put(SCAN_REFRESH, "Scan Refresh"); - attributes.put(SENSOR_LOCATION, "Sensor Location"); - attributes.put(SERIAL_NUMBER_STRING, "Serial Number String"); - attributes.put(SERVICE_CHANGED, "Service Changed"); - attributes.put(SOFTWARE_REVISION_STRING, "Software Revision String"); - attributes.put(SUPPORTED_NEW_ALERT_CATEGORY, "Supported New Alert Category"); - attributes.put(SUPPORTED_UNREAD_ALERT_CATEGORY, "Supported Unread Alert Category"); - attributes.put(SYSTEM_ID, "System ID"); - attributes.put(TEMPERATURE_MEASUREMENT, "Temperature Measurement"); - attributes.put(TEMPERATURE_TYPE, "Temperature Type"); - attributes.put(TIME_ACCURACY, "Time Accuracy"); - attributes.put(TIME_SOURCE, "Time Source"); - attributes.put(TIME_UPDATE_CONTROL_POINT, "Time Update Control Point"); - attributes.put(TIME_UPDATE_STATE, "Time Update State"); - attributes.put(TIME_WITH_DST, "Time with DST"); - attributes.put(TIME_ZONE, "Time Zone"); - attributes.put(TX_POWER_LEVEL, "Tx Power Level"); - attributes.put(UNREAD_ALERT_STATUS, "Unread Alert Status"); - attributes.put(AGGREGATE_INPUT, "Aggregate Input"); - attributes.put(ANALOG_INPUT, "Analog Input"); - attributes.put(ANALOG_OUTPUT, "Analog Output"); - attributes.put(DIGITAL_INPUT, "Digital Input"); - attributes.put(DIGITAL_OUTPUT, "Digital Output"); - attributes.put(EXACT_TIME_100, "Exact Time 100"); - attributes.put(NETWORK_AVAILABILITY, "Network Availability"); - attributes.put(SCIENTIFIC_TEMPERATURE_IN_CELSIUS, "Scientific Temperature in Celsius"); - attributes.put(SECONDARY_TIME_ZONE, "Secondary Time Zone"); - attributes.put(STRING, "String"); - attributes.put(TEMPERATURE_IN_CELSIUS, "Temperature in Celsius"); - attributes.put(TEMPERATURE_IN_FAHRENHEIT, "Temperature in Fahrenheit"); - attributes.put(TIME_BROADCAST, "Time Broadcast"); - attributes.put(BATTERY_LEVEL_STATE, "Battery Level State"); - attributes.put(BATTERY_POWER_STATE, "Battery Power State"); - attributes.put(PULSE_OXIMETRY_CONTINUOUS_MEASUREMENT, "Pulse Oximetry Continuous Measurement"); - attributes.put(PULSE_OXIMETRY_CONTROL_POINT, "Pulse Oximetry Control Point"); - attributes.put(PULSE_OXIMETRY_FEATURES, "Pulse Oximetry Features"); - attributes.put(PULSE_OXIMETRY_PULSATILE_EVENT, "Pulse Oximetry Pulsatile Event"); - attributes.put(PULSE_OXIMETRY_SPOT_CHECK_MEASUREMENT, "Pulse Oximetry Spot-Check Measurement"); - attributes.put(RECORD_ACCESS_CONTROL_POINT_TESTVERSION, "Record Access Control point (Test Version)"); - attributes.put(REMOVABLE, "Removable"); - attributes.put(SERVICE_REQUIRED, "Service Required"); - } - - public static String lookup(UUID uuid, String defaultName) { - String name = attributes.get(uuid); - return name == null ? defaultName : name; - } -} \ No newline at end of file diff --git a/src/main/java/com/movisens/smartgattlib/Descriptor.java b/src/main/java/com/movisens/smartgattlib/Descriptor.java deleted file mode 100644 index 85f2932..0000000 --- a/src/main/java/com/movisens/smartgattlib/Descriptor.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.movisens.smartgattlib; - -import java.util.HashMap; -import java.util.UUID; - -public class Descriptor { - public static final UUID CHARACTERISTIC_EXTENDED_PROPERTIES = new UUID((0x2900L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID CHARACTERISTIC_USER_DESCRIPTION = new UUID((0x2901L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID CLIENT_CHARACTERISTIC_CONFIGURATION = new UUID((0x2902L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID SERVER_CHARACTERISTIC_CONFIGURATION = new UUID((0x2903L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID CHARACTERISTIC_PRESENTATION_FORMAT = new UUID((0x2904L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID CHARACTERISTIC_AGGREGATE_FORMAT = new UUID((0x2905L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID VALID_RANGE = new UUID((0x2906L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID EXTERNAL_REPORT_REFERENCE = new UUID((0x2907L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID REPORT_REFERENCE = new UUID((0x2908L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID NUMBER_OF_DIGITALS = new UUID((0x2909L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID TRIGGER_SETTING = new UUID((0x290AL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID TEST_COMPLEX_BITFIELD = new UUID((0L << 32) | 0x1000, GattUtils.leastSigBits); - - private static HashMap attributes = new HashMap(); - static { - attributes.put(CHARACTERISTIC_EXTENDED_PROPERTIES, "Characteristic Extended Properties"); - attributes.put(CHARACTERISTIC_USER_DESCRIPTION, "Characteristic User Description"); - attributes.put(CLIENT_CHARACTERISTIC_CONFIGURATION, "Client Characteristic Configuration"); - attributes.put(SERVER_CHARACTERISTIC_CONFIGURATION, "Server Characteristic Configuration"); - attributes.put(CHARACTERISTIC_PRESENTATION_FORMAT, "Characteristic Presentation Format"); - attributes.put(CHARACTERISTIC_AGGREGATE_FORMAT, "Characteristic Aggregate Format"); - attributes.put(VALID_RANGE, "Valid Range"); - attributes.put(EXTERNAL_REPORT_REFERENCE, "External Report Reference"); - attributes.put(REPORT_REFERENCE, "Report Reference"); - attributes.put(NUMBER_OF_DIGITALS, "Number of Digitals"); - attributes.put(TRIGGER_SETTING, "Trigger Setting"); - attributes.put(TEST_COMPLEX_BITFIELD, "Test Complex BitField"); - } - - public static String lookup(UUID uuid, String defaultName) { - String name = attributes.get(uuid); - return name == null ? defaultName : name; - } -} \ No newline at end of file diff --git a/src/main/java/com/movisens/smartgattlib/Example.java b/src/main/java/com/movisens/smartgattlib/Example.java deleted file mode 100644 index 872f2f5..0000000 --- a/src/main/java/com/movisens/smartgattlib/Example.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.movisens.smartgattlib; - -import java.util.UUID; - -import com.movisens.smartgattlib.characteristics.HeartRateMeasurement; - - -public class Example { - - public static void main(String[] args) { - // onConnected - // TODO: iterate over available services - UUID serviceUuid = null;// service.getUuid(); - if (Service.HEART_RATE.equals(serviceUuid)) { - - // TODO: iterate over characteristics - UUID characteristicUuid = null;// characteristic.getUuid(); - if (Characteristic.HEART_RATE_MEASUREMENT.equals(characteristicUuid)) { - // TODO: Enable notification - //BluetoothGattDescriptor descriptor = characteristic.getDescriptor(Descriptor.CLIENT_CHARACTERISTIC_CONFIGURATION); - //descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); - //mBluetoothGatt.writeDescriptor(descriptor); - } - }else{ - System.out.println("Found unused Service: " + Service.lookup(serviceUuid, "unknown")); - } - - // onCharacteristicChanged - UUID characteristicUuid = null;// characteristic.getUuid(); - if (Characteristic.HEART_RATE_MEASUREMENT.equals(characteristicUuid)) { - byte[] value = null;// characteristic.getValue(); - HeartRateMeasurement hrm = new HeartRateMeasurement(value); - hrm.getHr(); - hrm.getEe(); - } - } -} diff --git a/src/main/java/com/movisens/smartgattlib/GattByteBuffer.java b/src/main/java/com/movisens/smartgattlib/GattByteBuffer.java deleted file mode 100644 index bbb180d..0000000 --- a/src/main/java/com/movisens/smartgattlib/GattByteBuffer.java +++ /dev/null @@ -1,185 +0,0 @@ -package com.movisens.smartgattlib; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -public class GattByteBuffer { - - public static GattByteBuffer allocate(int i) { - GattByteBuffer result = new GattByteBuffer(); - result.buffer = ByteBuffer.allocate(i); - result.buffer.order(ByteOrder.LITTLE_ENDIAN); - return result; - } - - public static GattByteBuffer wrap(byte[] byteArray) { - GattByteBuffer result = new GattByteBuffer(); - result.buffer = ByteBuffer.wrap(byteArray); - result.buffer.order(ByteOrder.LITTLE_ENDIAN); - return result; - } - - private ByteBuffer buffer; - - public byte[] array() { - return buffer.array(); - } - - public final int capacity() { - return buffer.capacity(); - } - - public void getInt8(byte[] value, int i, int j) { - buffer.get(value, i, j); - } - - public void getUint8(short[] value, int offset, int length) { - for (int i = 0; i < length; i++) { - value[i + offset] = getUint8(); - } - } - - public Boolean getBoolean() { - if (buffer.get() == (byte) 0) { - return false; - } else { - return true; - } - } - - public Float getFloat32() { - return buffer.getFloat(); - } - - public Short getInt16() { - return buffer.getShort(); - } - - public Integer getInt32() { - return buffer.getInt(); - } - - public Long getInt64() { - return buffer.getLong(); - } - - public Byte getInt8() { - return buffer.get(); - } - - public String getString() { - String result = ""; - byte c; - - while ((c = buffer.get()) != 0) { - result += (char) c; - } - - return result; - } - - public Integer getUint16() { - int result = buffer.getShort(); - if (result < 0) { - result += ((int) 1) << 16; - } - return result; - } - - public Long getUint32() { - long result = buffer.getInt(); - if (result < 0) { - result += ((long) 1) << 32; - } - return result; - } - - public Short getUint8() { - short result = buffer.get(); - if (result < 0) { - result += ((short) 1) << 8; - } - return result; - } - - public GattByteBuffer position(int i) { - buffer.position(i); - return this; - } - - public GattByteBuffer putUint8(short[] value, int offset, int length) { - for (int i = 0; i < length; i++) { - putUint8(value[i + offset]); - } - return this; - } - - public GattByteBuffer putInt8(byte[] value, int i, int j) { - buffer.put(value, i, j); - return this; - } - - public GattByteBuffer putBoolean(boolean doEnable) { - if (doEnable) { - buffer.put((byte) 1); - } else { - buffer.put((byte) 0); - } - return this; - } - - public GattByteBuffer putFloat32(Float value) { - buffer.putFloat(value); - return this; - } - - public GattByteBuffer putInt16(short value) { - buffer.putShort(value); - return this; - } - - public GattByteBuffer putInt32(int value) { - buffer.putInt(value); - return this; - } - - public GattByteBuffer putInt64(long value) { - buffer.putLong(value); - return this; - } - - public GattByteBuffer putInt8(byte value) { - buffer.put(value); - return this; - } - - public GattByteBuffer putString(String value) { - buffer.put(value.getBytes()); - buffer.put((byte) 0); - return this; - } - - public GattByteBuffer putUint16(int value) { - buffer.putShort((short) value); - return this; - } - - public GattByteBuffer putUint32(long value) { - buffer.putInt((int) value); - return this; - } - - public GattByteBuffer putUint8(short value) { - buffer.put((byte) value); - return this; - } - - public GattByteBuffer rewind() { - buffer.rewind(); - return this; - } - - public boolean hasRemaining() { - return buffer.hasRemaining(); - } -} diff --git a/src/main/java/com/movisens/smartgattlib/Service.java b/src/main/java/com/movisens/smartgattlib/Service.java deleted file mode 100644 index 3174f0a..0000000 --- a/src/main/java/com/movisens/smartgattlib/Service.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.movisens.smartgattlib; - -import java.util.HashMap; -import java.util.UUID; - -public class Service { - public static final UUID ALERT_NOTIFICATION_SERVICE = new UUID((0x1811L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID BATTERY_SERVICE = new UUID((0x180FL << 32) | 0x1000,GattUtils.leastSigBits); - public static final UUID BLOOD_PRESSURE = new UUID((0x1810L << 32) | 0x1000,GattUtils.leastSigBits); - public static final UUID CURRENT_TIME_SERVICE = new UUID((0x1805L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID CYCLING_POWER = new UUID((0x1818L << 32) | 0x1000,GattUtils.leastSigBits); - public static final UUID CYCLING_SPEED_AND_CADENCE = new UUID((0x1816L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID DEVICE_INFORMATION = new UUID((0x180AL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID GENERIC_ACCESS = new UUID((0x1800L << 32) | 0x1000,GattUtils.leastSigBits); - public static final UUID GENERIC_ATTRIBUTE = new UUID((0x1801L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID GLUCOSE = new UUID((0x1808L << 32) | 0x1000,GattUtils.leastSigBits); - public static final UUID HEALTH_THERMOMETER = new UUID((0x1809L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID HEART_RATE = new UUID((0x180DL << 32) | 0x1000,GattUtils.leastSigBits); - public static final UUID HUMAN_INTERFACE_DEVICE = new UUID((0x1812L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID IMMEDIATE_ALERT = new UUID((0x1802L << 32) | 0x1000,GattUtils.leastSigBits); - public static final UUID LINK_LOSS = new UUID((0x1803L << 32) | 0x1000,GattUtils.leastSigBits); - public static final UUID LOCATION_AND_NAVIGATION = new UUID((0x1819L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID NEXT_DST_CHANGE_SERVICE = new UUID((0x1807L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID PHONE_ALERT_STATUS_SERVICE = new UUID((0x180EL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID REFERENCE_TIME_UPDATE_SERVICE = new UUID((0x1806L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID RUNNING_SPEED_AND_CADENCE = new UUID((0x1814L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID SCAN_PARAMETERS = new UUID((0x1813L << 32) | 0x1000,GattUtils.leastSigBits); - public static final UUID TX_POWER = new UUID((0x1804L << 32) | 0x1000,GattUtils.leastSigBits); - public static final UUID AUTOMATION_IO = new UUID((0x1815L << 32) | 0x1000,GattUtils.leastSigBits); - public static final UUID BATTERY_SERVICE_1_1 = new UUID((0x180FL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID IMMEDIATE_ALERT_SERVICE_1_1 = new UUID((0x1802L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID LINK_LOSS_SERVICE_1_1 = new UUID((0x1803L << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID NETWORK_AVAILABILITY_SERVICE = new UUID((0x180BL << 32) | 0x1000, GattUtils.leastSigBits); - public static final UUID TX_POWER_SERVICE_1_1 = new UUID((0x1804L << 32) | 0x1000, GattUtils.leastSigBits); - - private static HashMap attributes = new HashMap(); - static { - attributes.put(ALERT_NOTIFICATION_SERVICE, "Alert Notification Service"); - attributes.put(BATTERY_SERVICE, "Battery Service"); - attributes.put(BLOOD_PRESSURE, "Blood Pressure"); - attributes.put(CURRENT_TIME_SERVICE, "Current Time Service"); - attributes.put(CYCLING_POWER, "Cycling Power"); - attributes.put(CYCLING_SPEED_AND_CADENCE, "Cycling Speed and Cadence"); - attributes.put(DEVICE_INFORMATION, "Device Information"); - attributes.put(GENERIC_ACCESS, "Generic Access"); - attributes.put(GENERIC_ATTRIBUTE, "Generic Attribute"); - attributes.put(GLUCOSE, "Glucose"); - attributes.put(HEALTH_THERMOMETER, "Health Thermometer"); - attributes.put(HEART_RATE, "Heart Rate"); - attributes.put(HUMAN_INTERFACE_DEVICE, "Human Interface Device"); - attributes.put(IMMEDIATE_ALERT, "Immediate Alert"); - attributes.put(LINK_LOSS, "Link Loss"); - attributes.put(LOCATION_AND_NAVIGATION, "Location and Navigation"); - attributes.put(NEXT_DST_CHANGE_SERVICE, "Next DST Change Service"); - attributes.put(PHONE_ALERT_STATUS_SERVICE, "Phone Alert Status Service"); - attributes.put(REFERENCE_TIME_UPDATE_SERVICE, "Reference Time Update Service"); - attributes.put(RUNNING_SPEED_AND_CADENCE, "Running Speed and Cadence"); - attributes.put(SCAN_PARAMETERS, "Scan Parameters"); - attributes.put(TX_POWER, "Tx Power"); - attributes.put(AUTOMATION_IO, "Automation IO"); - attributes.put(BATTERY_SERVICE_1_1, "Battery Service v1.1"); - attributes.put(IMMEDIATE_ALERT_SERVICE_1_1, "Immediate Alert Service 1.1"); - attributes.put(LINK_LOSS_SERVICE_1_1, "Link Loss Service 1.1"); - attributes.put(NETWORK_AVAILABILITY_SERVICE, "Network Availability Service"); - attributes.put(TX_POWER_SERVICE_1_1, "Tx Power Service 1.1"); - } - - public static String lookup(UUID uuid, String defaultName) { - String name = attributes.get(uuid); - return name == null ? defaultName : name; - } -} \ No newline at end of file diff --git a/src/main/java/com/movisens/smartgattlib/attributes/BodySensorLocation.java b/src/main/java/com/movisens/smartgattlib/attributes/BodySensorLocation.java new file mode 100644 index 0000000..a11443c --- /dev/null +++ b/src/main/java/com/movisens/smartgattlib/attributes/BodySensorLocation.java @@ -0,0 +1,71 @@ +package com.movisens.smartgattlib.attributes; + +import com.movisens.smartgattlib.Characteristics; +import com.movisens.smartgattlib.helper.AbstractReadAttribute; +import com.movisens.smartgattlib.helper.Characteristic; +import com.movisens.smartgattlib.helper.GattByteBuffer; + +public class BodySensorLocation extends AbstractReadAttribute { + + public enum Location { + Other, Chest, Wrist, Finger, Hand, Ear_Lobe, Foot; + } + + public static final Characteristic CHARACTERISTIC = Characteristics.BODY_SENSOR_LOCATION; + + private Location location; + + public Location getLocation() + { + return location; + } + + public String getLocationUnit() + { + return ""; + } + + public BodySensorLocation(byte[] data) + { + this.data = data; + location = Location.Other; + int loc = GattByteBuffer.wrap(data).getUint8(); + + switch (loc) { + case 0: + location = Location.Other; + break; + case 1: + location = Location.Chest; + break; + case 2: + location = Location.Wrist; + break; + case 3: + location = Location.Finger; + break; + case 4: + location = Location.Hand; + break; + case 5: + location = Location.Ear_Lobe; + break; + case 6: + location = Location.Foot; + break; + } + } + + @Override + public Characteristic getCharacteristic() + { + return CHARACTERISTIC; + } + + @Override + public String toString() + { + return "BodySensorLocation: " + "location = " + getLocation() + " " + getLocationUnit(); + } + +} diff --git a/src/main/java/com/movisens/smartgattlib/characteristics/CyclingSpeedCadenceMeasurement.java b/src/main/java/com/movisens/smartgattlib/attributes/CscMeasurement.java similarity index 73% rename from src/main/java/com/movisens/smartgattlib/characteristics/CyclingSpeedCadenceMeasurement.java rename to src/main/java/com/movisens/smartgattlib/attributes/CscMeasurement.java index 398557f..b532fcc 100644 --- a/src/main/java/com/movisens/smartgattlib/characteristics/CyclingSpeedCadenceMeasurement.java +++ b/src/main/java/com/movisens/smartgattlib/attributes/CscMeasurement.java @@ -1,9 +1,14 @@ -package com.movisens.smartgattlib.characteristics; +package com.movisens.smartgattlib.attributes; -import com.movisens.smartgattlib.GattByteBuffer; +import com.movisens.smartgattlib.Characteristics; import com.movisens.smartgattlib.GattUtils; +import com.movisens.smartgattlib.helper.AbstractReadAttribute; +import com.movisens.smartgattlib.helper.Characteristic; +import com.movisens.smartgattlib.helper.GattByteBuffer; -public class CyclingSpeedCadenceMeasurement { +public class CscMeasurement extends AbstractReadAttribute { + + public static final Characteristic CHARACTERISTIC = Characteristics.CSC_MEASUREMENT; public static final int MAX_CUMULATIVE_CRANK_REVS = 65535; public static final long MAX_CUMULATIVE_WHEEL_REVS = 4294967295L; @@ -16,10 +21,9 @@ public class CyclingSpeedCadenceMeasurement { private int cumulativeCrankRevolutions; private int lastCrankEventTime; - public CyclingSpeedCadenceMeasurement(byte[] value) { - super(); - - GattByteBuffer bb = GattByteBuffer.wrap(value); + public CscMeasurement(byte[] data) { + this.data = data; + GattByteBuffer bb = GattByteBuffer.wrap(data); byte flags = bb.getInt8(); wheelRevPresent = wheelRevPresent(flags); @@ -49,7 +53,7 @@ public long getCumulativeWheelRevolutions() { } //unit has resolution of 1/1024s - public int getLastWheelEventTime() { + public int getWheelEventTime() { return lastWheelEventTime; } @@ -58,7 +62,7 @@ public int getCumulativeCrankRevolutions() { } //unit has resolution of 1/1024s - public int getLastCrankEventTime() { + public int getCrankEventTime() { return lastCrankEventTime; } @@ -70,6 +74,11 @@ private boolean crankRevPresent(byte flags) { return (flags & GattUtils.SECOND_BITMASK) != 0; } + @Override + public Characteristic getCharacteristic() { + return CHARACTERISTIC; + } + @Override public String toString() { return "SpeedCadenceMeasurement{" + @@ -81,4 +90,4 @@ public String toString() { ", lastCrankEventTime=" + lastCrankEventTime + '}'; } -} +} \ No newline at end of file diff --git a/src/main/java/com/movisens/smartgattlib/attributes/DefaultAttribute.java b/src/main/java/com/movisens/smartgattlib/attributes/DefaultAttribute.java new file mode 100644 index 0000000..0853c26 --- /dev/null +++ b/src/main/java/com/movisens/smartgattlib/attributes/DefaultAttribute.java @@ -0,0 +1,43 @@ +package com.movisens.smartgattlib.attributes; + +import com.movisens.smartgattlib.Characteristics; +import com.movisens.smartgattlib.helper.AbstractAttribute; +import com.movisens.smartgattlib.helper.Characteristic; + +public class DefaultAttribute extends AbstractAttribute +{ + + public DefaultAttribute(byte[] data) + { + this.data = data; + } + + @Override + public Characteristic getCharacteristic() + { + return Characteristics.DEFAULT; + } + + @Override + public String toString() + { + String result = this.getClass().getSimpleName() + " = "; + for (byte d : data) + { + result += String.format("0x%02x ", d); + } + return result; + } + + @Override + public boolean isReadable() + { + return false; + } + + @Override + public boolean isWritable() + { + return false; + } +} diff --git a/src/main/java/com/movisens/smartgattlib/attributes/HeartRateMeasurement.java b/src/main/java/com/movisens/smartgattlib/attributes/HeartRateMeasurement.java new file mode 100644 index 0000000..cb72a7e --- /dev/null +++ b/src/main/java/com/movisens/smartgattlib/attributes/HeartRateMeasurement.java @@ -0,0 +1,110 @@ +package com.movisens.smartgattlib.attributes; + +import java.util.ArrayList; + +import com.movisens.smartgattlib.Characteristics; +import com.movisens.smartgattlib.GattUtils; +import com.movisens.smartgattlib.helper.AbstractReadAttribute; +import com.movisens.smartgattlib.helper.Characteristic; +import com.movisens.smartgattlib.helper.GattByteBuffer; + +public class HeartRateMeasurement extends AbstractReadAttribute +{ + + public static final Characteristic CHARACTERISTIC = Characteristics.HEART_RATE_MEASUREMENT; + + ArrayList rrIntervals = new ArrayList(); + int hrmval = 0; + int eeval = -1; + byte flags; + HeartRateMeasurement.SensorWorn sensorWorn = HeartRateMeasurement.SensorWorn.UNSUPPORTED; + + public enum SensorWorn { + UNSUPPORTED, WORN, NOT_WORN + } + + public HeartRateMeasurement(byte[] data) + { + this.data = data; + GattByteBuffer bb = GattByteBuffer.wrap(data); + flags = bb.getInt8(); + if (isHeartRateInUINT16()) { + hrmval = bb.getUint16(); + } else { + hrmval = bb.getUint8(); + } + if (isWornStatusPresent()) { + if (isSensorWorn()) { + sensorWorn = HeartRateMeasurement.SensorWorn.WORN; + } else { + sensorWorn = HeartRateMeasurement.SensorWorn.NOT_WORN; + } + } + if (isEePresent()) { + eeval = bb.getUint16(); + } + if (isRrIntPresent()) { + while (bb.hasRemaining()) { + rrIntervals.add(bb.getUint16() / 1024F); + } + } + } + + public boolean isHeartRateInUINT16() { + return (flags & GattUtils.FIRST_BITMASK) != 0; + } + + public boolean isWornStatusPresent() { + return (flags & GattUtils.THIRD_BITMASK) != 0; + } + + public boolean isSensorWorn() { + return (flags & GattUtils.SECOND_BITMASK) != 0; + } + + public boolean isEePresent() { + return (flags & GattUtils.FOURTH_BITMASK) != 0; + } + + public boolean isRrIntPresent() { + return (flags & GattUtils.FIFTH_BITMASK) != 0; + } + + /** + * @return RR-Intervals. Units: seconds + */ + public ArrayList getRrIntervals() { + return rrIntervals; + } + + public int getHr() { + return hrmval; + } + + public String getHrUnit() { + return "bpm"; + } + + /** + * @return Energy Expended, Units: kilo Joules + */ + public int getEe() { + return eeval; + } + + public SensorWorn getSensorWorn() { + return sensorWorn; + } + + @Override + public Characteristic getCharacteristic() + { + return CHARACTERISTIC; + } + + @Override + public String toString() + { + return "Heart Rate Measurement: " + "hr = " + getHr() + " " + getHrUnit() + ", " + "ee = " + getEe() + ", " + "sensorworn = " + getSensorWorn(); + } +} diff --git a/src/main/java/com/movisens/smartgattlib/characteristics/BatteryLevel.java b/src/main/java/com/movisens/smartgattlib/characteristics/BatteryLevel.java deleted file mode 100644 index c75d39f..0000000 --- a/src/main/java/com/movisens/smartgattlib/characteristics/BatteryLevel.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.movisens.smartgattlib.characteristics; - -import com.movisens.smartgattlib.GattByteBuffer; - -public class BatteryLevel { - int level = -1; - - public BatteryLevel(byte[] value) { - level = GattByteBuffer.wrap(value).getUint8(); - } - - /** - * @return The current charge level of a battery in %. 100% represents fully - * charged while 0% represents fully discharged. - */ - public int getBatteryLevel() { - return level; - } -} diff --git a/src/main/java/com/movisens/smartgattlib/characteristics/BodySensorLocation.java b/src/main/java/com/movisens/smartgattlib/characteristics/BodySensorLocation.java deleted file mode 100644 index 193a993..0000000 --- a/src/main/java/com/movisens/smartgattlib/characteristics/BodySensorLocation.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.movisens.smartgattlib.characteristics; - -import com.movisens.smartgattlib.GattByteBuffer; - -public class BodySensorLocation { - Location location = Location.Other; - - public enum Location { - Other, Chest, Wrist, Finger, Hand, Ear_Lobe, Foot; - } - - public BodySensorLocation(byte[] value) { - int loc = GattByteBuffer.wrap(value).getUint8(); - - switch (loc) { - case 0: - location = Location.Other; - break; - case 1: - location = Location.Chest; - break; - case 2: - location = Location.Wrist; - break; - case 3: - location = Location.Finger; - break; - case 4: - location = Location.Hand; - break; - case 5: - location = Location.Ear_Lobe; - break; - case 6: - location = Location.Foot; - break; - } - } - - /** - * @return The current location of the sensor - */ - public Location getBodySensorLocation() { - return location; - } -} diff --git a/src/main/java/com/movisens/smartgattlib/characteristics/HeartRateMeasurement.java b/src/main/java/com/movisens/smartgattlib/characteristics/HeartRateMeasurement.java deleted file mode 100644 index 0f13bb3..0000000 --- a/src/main/java/com/movisens/smartgattlib/characteristics/HeartRateMeasurement.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.movisens.smartgattlib.characteristics; - -import java.util.ArrayList; - -import com.movisens.smartgattlib.GattByteBuffer; -import com.movisens.smartgattlib.GattUtils; - -public class HeartRateMeasurement { - - ArrayList rrIntervals = new ArrayList(); - int hrmval = 0; - int eeval = -1; - SensorWorn sensorWorn = SensorWorn.UNSUPPORTED; - - public enum SensorWorn { - UNSUPPORTED, WORN, NOT_WORN - } - - public HeartRateMeasurement(byte[] value) { - GattByteBuffer bb = GattByteBuffer.wrap(value); - byte flags = bb.getInt8(); - if (isHeartRateInUINT16(flags)) { - hrmval = bb.getUint16(); - } else { - hrmval = bb.getUint8(); - } - if (isWornStatusPresent(flags)) { - if (isSensorWorn(flags)) { - sensorWorn = SensorWorn.WORN; - } else { - sensorWorn = SensorWorn.NOT_WORN; - } - } - if (isEePresent(flags)) { - eeval = bb.getUint16(); - } - if (isRrIntPresent(flags)) { - while (bb.hasRemaining()) { - rrIntervals.add(bb.getUint16() / 1024F); - } - } - } - - private boolean isHeartRateInUINT16(byte flags) { - if ((flags & GattUtils.FIRST_BITMASK) != 0) - return true; - return false; - } - - private boolean isWornStatusPresent(byte flags) { - if ((flags & GattUtils.THIRD_BITMASK) != 0) - return true; - return false; - } - - private boolean isSensorWorn(byte flags) { - if ((flags & GattUtils.SECOND_BITMASK) != 0) - return true; - return false; - } - - private boolean isEePresent(byte flags) { - if ((flags & GattUtils.FOURTH_BITMASK) != 0) - return true; - return false; - } - - private boolean isRrIntPresent(byte flags) { - if ((flags & GattUtils.FIFTH_BITMASK) != 0) - return true; - return false; - } - - /** - * @return RR-Intervals. Units: seconds - */ - public ArrayList getRrInterval() { - return rrIntervals; - } - - public int getHr() { - return hrmval; - } - - /** - * @return Energy Expended, Units: kilo Joules - */ - public int getEe() { - return eeval; - } - - public SensorWorn getSensorWorn() { - return sensorWorn; - } -} diff --git a/src/main/java/com/movisens/smartgattlib/characteristics/ManufacturerNameString.java b/src/main/java/com/movisens/smartgattlib/characteristics/ManufacturerNameString.java deleted file mode 100644 index ab7493c..0000000 --- a/src/main/java/com/movisens/smartgattlib/characteristics/ManufacturerNameString.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.movisens.smartgattlib.characteristics; - -import com.movisens.smartgattlib.GattByteBuffer; - -public class ManufacturerNameString { - String content = ""; - - public ManufacturerNameString(byte[] value) { - content = GattByteBuffer.wrap(value).getString(); - } - - public String getManufacturerNameString() { - return content; - } -} diff --git a/src/main/java/com/movisens/smartgattlib/declarations/CharacteristicDeclaration.java b/src/main/java/com/movisens/smartgattlib/declarations/CharacteristicDeclaration.java new file mode 100644 index 0000000..18ab24d --- /dev/null +++ b/src/main/java/com/movisens/smartgattlib/declarations/CharacteristicDeclaration.java @@ -0,0 +1,89 @@ +package com.movisens.smartgattlib.declarations; + +import java.util.UUID; + +import com.movisens.smartgattlib.helper.GattByteBuffer; +import com.movisens.smartgattlib.helper.UuidObject; + +public class CharacteristicDeclaration +{ + + enum EnumCharacteristicProperties { + + Broadcast(0), Read(1), WriteWithoutResponse(2), Write(3), Notify(4), Indicate(5), AuthenticatedSignedWrites(6), ExtendedProperties(7); + + private final byte value; + + EnumCharacteristicProperties(int bitNumber) + { + this.value = (byte) (((byte) 1) << bitNumber); + } + } + + public static final UUID uuid = UuidObject.stringToUuid("2803"); + + private byte[] data; + + private short characteristicProperties; + + private int characteristicValueHandle; + + private UUID characteristicUuid; + + public CharacteristicDeclaration(byte[] data) + { + this.data = data; + GattByteBuffer bb = GattByteBuffer.wrap(data); + characteristicProperties = bb.getUint8(); + characteristicValueHandle = bb.getUint16(); + characteristicUuid = bb.getUuid(); + } + + public boolean supportsNotify() + { + return (characteristicProperties & EnumCharacteristicProperties.Notify.value) != 0; + } + + public boolean supportsIndicate() + { + return (characteristicProperties & EnumCharacteristicProperties.Indicate.value) != 0; + } + + public byte[] getData() + { + return data; + } + + public short getCharacteristicProperties() + { + return characteristicProperties; + } + + public int getCharacteristicValueHandle() + { + return characteristicValueHandle; + } + + public UUID getCharacteristicUuid() + { + return characteristicUuid; + } + + @Override + public String toString() + { + String string = "CharacteristicDeclaration"; + string += " handle: " + characteristicValueHandle; + string += " properties: "; + for (EnumCharacteristicProperties cp : EnumCharacteristicProperties.values()) + { + if ((characteristicProperties & cp.value) == cp.value) + { + string += cp.name().toUpperCase() + " "; + } + } + string += " uuid: " + characteristicUuid.toString(); + return string; + } + +} diff --git a/src/main/java/com/movisens/smartgattlib/descriptors/ClientCharacteristicConfiguration.java b/src/main/java/com/movisens/smartgattlib/descriptors/ClientCharacteristicConfiguration.java new file mode 100644 index 0000000..af54f8e --- /dev/null +++ b/src/main/java/com/movisens/smartgattlib/descriptors/ClientCharacteristicConfiguration.java @@ -0,0 +1,42 @@ +package com.movisens.smartgattlib.descriptors; + +import java.util.UUID; + +import com.movisens.smartgattlib.helper.GattByteBuffer; +import com.movisens.smartgattlib.helper.UuidObject; + +public class ClientCharacteristicConfiguration +{ + + public enum EnumProperties { + + Notifications(0), Indications(1); + + private final byte value; + + EnumProperties(int bitNumber) + { + this.value = (byte) (((byte) 1) << bitNumber); + } + } + + public static final UUID uuid = UuidObject.stringToUuid("2902"); + + private byte[] data; + + private EnumProperties properties; + + public ClientCharacteristicConfiguration(EnumProperties properties) + { + this.properties = properties; + GattByteBuffer bb = GattByteBuffer.allocate(2); + bb.putUint16(this.properties.value); + this.data = bb.array(); + } + + public byte[] getBytes() + { + return data; + } + +} diff --git a/src/main/java/com/movisens/smartgattlib/helper/AbstractAttribute.java b/src/main/java/com/movisens/smartgattlib/helper/AbstractAttribute.java new file mode 100644 index 0000000..1ae3073 --- /dev/null +++ b/src/main/java/com/movisens/smartgattlib/helper/AbstractAttribute.java @@ -0,0 +1,65 @@ +package com.movisens.smartgattlib.helper; + +import com.movisens.smartgattlib.security.CryptoManager; + +public abstract class AbstractAttribute +{ + + protected byte[] data; + + public byte[] getBytes() + { + return data; + } + + /** + * Get data to be sent via BLE. This data may be encrypted. + * + * @return data to send via BLE + */ + public byte[] getOutgoingData(CryptoManager cryptoManager) + { + if (getCharacteristic().isEncryptionAllowed()) + { + return cryptoManager.processBeforeSend(data); + } + else + { + return data; + } + } + + /** + * Gets the raw data representation of this attribute. This data is not encrypted. + * + * @return raw data representation + */ + public byte[] getRawData() + { + return data; + } + + public abstract Characteristic getCharacteristic(); + + public boolean isReadable() + { + return false; + } + + public boolean isWritable() + { + return false; + } + + @Override + public String toString() + { + String result = ""; + for (byte b : data) + { + result += String.format("0x%02x ", b); + } + + return result; + } +} diff --git a/src/main/java/com/movisens/smartgattlib/helper/AbstractReadAttribute.java b/src/main/java/com/movisens/smartgattlib/helper/AbstractReadAttribute.java new file mode 100644 index 0000000..e4aed80 --- /dev/null +++ b/src/main/java/com/movisens/smartgattlib/helper/AbstractReadAttribute.java @@ -0,0 +1,19 @@ +package com.movisens.smartgattlib.helper; + + +public abstract class AbstractReadAttribute extends AbstractAttribute +{ + + @Override + public boolean isReadable() + { + return true; + } + + @Override + public boolean isWritable() + { + return false; + } + +} diff --git a/src/main/java/com/movisens/smartgattlib/helper/AbstractReadWriteAttribute.java b/src/main/java/com/movisens/smartgattlib/helper/AbstractReadWriteAttribute.java new file mode 100644 index 0000000..25678cc --- /dev/null +++ b/src/main/java/com/movisens/smartgattlib/helper/AbstractReadWriteAttribute.java @@ -0,0 +1,18 @@ +package com.movisens.smartgattlib.helper; + + +public abstract class AbstractReadWriteAttribute extends AbstractAttribute +{ + @Override + public boolean isReadable() + { + return true; + } + + @Override + public boolean isWritable() + { + return true; + } + +} diff --git a/src/main/java/com/movisens/smartgattlib/helper/AbstractWriteAttribute.java b/src/main/java/com/movisens/smartgattlib/helper/AbstractWriteAttribute.java new file mode 100644 index 0000000..f800146 --- /dev/null +++ b/src/main/java/com/movisens/smartgattlib/helper/AbstractWriteAttribute.java @@ -0,0 +1,18 @@ +package com.movisens.smartgattlib.helper; + +public abstract class AbstractWriteAttribute extends AbstractAttribute +{ + + @Override + public boolean isReadable() + { + return false; + } + + @Override + public boolean isWritable() + { + return true; + } + +} diff --git a/src/main/java/com/movisens/smartgattlib/helper/Characteristic.java b/src/main/java/com/movisens/smartgattlib/helper/Characteristic.java new file mode 100644 index 0000000..d4694b6 --- /dev/null +++ b/src/main/java/com/movisens/smartgattlib/helper/Characteristic.java @@ -0,0 +1,88 @@ +package com.movisens.smartgattlib.helper; + +import java.lang.reflect.Constructor; +import java.util.Arrays; +import java.util.function.Predicate; + +import com.movisens.smartgattlib.attributes.DefaultAttribute; +import com.movisens.smartgattlib.security.CryptoManager; + +public class Characteristic extends UuidObject +{ + + private Class attributeClass; + + Characteristic requiredCharacteristics[]; + + public Characteristic[] getRequiredCharacteristics() + { + return requiredCharacteristics; + } + + public Characteristic(String uuid, String name, Class attributeClass, Characteristic... requiredCharacteristics) + { + super(uuid, name); + this.attributeClass = attributeClass; + this.requiredCharacteristics = requiredCharacteristics; + } + + public AbstractAttribute createAttribute(byte[] data) + { + try + { + return attributeClass.getConstructor(byte[].class).newInstance(data); + } + catch (Throwable e) + { + e.printStackTrace(); + return new DefaultAttribute(data); + } + } + + public AbstractAttribute createAttribute(CryptoManager cryptoManager, byte[] incommingData) + { + try + { + Constructor constructor = attributeClass.getConstructor(byte[].class); + + if (isEncryptionAllowed()) + { + return constructor.newInstance(cryptoManager.processAfterReceive(incommingData)); + } + else + { + return constructor.newInstance(incommingData); + } + } + catch (Throwable e) + { + e.printStackTrace(); + return new DefaultAttribute(incommingData); + } + } + + public Class getAttributeClass() + { + return attributeClass; + } + + public boolean isEncryptionAllowed() + { + return Arrays.stream(attributeClass.getInterfaces()).filter(new Predicate>() + { + + @Override + public boolean test(Class i) + { + return i.getName().equals(PlainTextAttribute.class.getName()); + } + }).count() == 0; + } + + @Override + public String toString() + { + return getName(); + } + +} diff --git a/src/main/java/com/movisens/smartgattlib/helper/GattByteBuffer.java b/src/main/java/com/movisens/smartgattlib/helper/GattByteBuffer.java new file mode 100644 index 0000000..cde22b7 --- /dev/null +++ b/src/main/java/com/movisens/smartgattlib/helper/GattByteBuffer.java @@ -0,0 +1,284 @@ +package com.movisens.smartgattlib.helper; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.Date; +import java.util.UUID; + +public class GattByteBuffer +{ + + public static GattByteBuffer allocate(int i) + { + GattByteBuffer result = new GattByteBuffer(); + result.buffer = ByteBuffer.allocate(i); + result.buffer.order(ByteOrder.LITTLE_ENDIAN); + return result; + } + + public static GattByteBuffer wrap(byte[] byteArray) + { + GattByteBuffer result = new GattByteBuffer(); + result.buffer = ByteBuffer.wrap(byteArray); + result.buffer.order(ByteOrder.LITTLE_ENDIAN); + return result; + } + + private ByteBuffer buffer; + + public byte[] array() + { + return buffer.array(); + } + + public final int capacity() + { + return buffer.capacity(); + } + + public void getInt8(byte[] value, int i, int j) + { + buffer.get(value, i, j); + } + + public void getUint8(short[] value, int offset, int length) + { + for (int i = 0; i < length; i++) + { + value[i + offset] = getUint8(); + } + } + + public Boolean getBoolean() + { + if (buffer.get() == (byte) 0) + { + return false; + } + else + { + return true; + } + } + + public Float getFloat32() + { + return buffer.getFloat(); + } + + public Short getInt16() + { + return buffer.getShort(); + } + + public Integer getInt32() + { + return buffer.getInt(); + } + + public Long getInt64() + { + return buffer.getLong(); + } + + public Byte getInt8() + { + return buffer.get(); + } + + public String getString() + { + String result = ""; + byte c; + + while (buffer.hasRemaining() && ((c = buffer.get()) != 0)) + { + result += (char) c; + } + + return result; + } + + public Integer getUint16() + { + int result = buffer.getShort(); + if (result < 0) + { + result += ((int) 1) << 16; + } + return result; + } + + public Long getUint32() + { + long result = buffer.getInt(); + if (result < 0) + { + result += ((long) 1) << 32; + } + return result; + } + + public Short getUint8() + { + short result = buffer.get(); + if (result < 0) + { + result += ((short) 1) << 8; + } + return result; + } + + public GattByteBuffer position(int i) + { + buffer.position(i); + return this; + } + + public GattByteBuffer putUint8(short[] value, int offset, int length) + { + for (int i = 0; i < length; i++) + { + putUint8(value[i + offset]); + } + return this; + } + + public GattByteBuffer putInt8(byte[] value, int i, int j) + { + buffer.put(value, i, j); + return this; + } + + public GattByteBuffer putBoolean(boolean doEnable) + { + if (doEnable) + { + buffer.put((byte) 1); + } + else + { + buffer.put((byte) 0); + } + return this; + } + + public GattByteBuffer putFloat32(Float value) + { + buffer.putFloat(value); + return this; + } + + public GattByteBuffer putInt16(short value) + { + buffer.putShort(value); + return this; + } + + public GattByteBuffer putInt32(int value) + { + buffer.putInt(value); + return this; + } + + public GattByteBuffer putInt64(long value) + { + buffer.putLong(value); + return this; + } + + public GattByteBuffer putInt8(byte value) + { + buffer.put(value); + return this; + } + + public GattByteBuffer putString(String value) + { + buffer.put(value.getBytes()); + buffer.put((byte) 0); + return this; + } + + public GattByteBuffer putUint16(int value) + { + buffer.putShort((short) value); + return this; + } + + public GattByteBuffer putUint32(long value) + { + buffer.putInt((int) value); + return this; + } + + public GattByteBuffer putUint8(short value) + { + buffer.put((byte) value); + return this; + } + + public GattByteBuffer rewind() + { + buffer.rewind(); + return this; + } + + public boolean hasRemaining() + { + return buffer.hasRemaining(); + } + + public void putStime(Date date) + { + putUint32(date.getTime()/1000); + } + + public Date getStime() + { + return new Date(getUint32()*1000); + } + + public void putMstime(Date date) + { + putInt64(date.getTime()); + } + + public Date getMstime() + { + return new Date(getInt64()); + } + + public void putTimezone(String zoneId) + { + String stzs = TimeZoneUtil.toShortTimeZone(zoneId); + putString(stzs); + } + + public String getTimezone() + { + String stzs = getString(); + String ltzs = TimeZoneUtil.toLongTimeZone(stzs); + return ltzs; + } + + public UUID getUuid() + { + int length = buffer.remaining(); + byte[] data = new byte[length]; + buffer.get(data); + + String uuidString = ""; + + for (int i = data.length - 1; i >= 0; i--) + { + if (i == 5 || i == 7 || i == 9 || i == 11) + { + uuidString += "-"; + } + uuidString += String.format("%02x", data[i]); + } + + return UuidObject.stringToUuid(uuidString); + } +} \ No newline at end of file diff --git a/src/main/java/com/movisens/smartgattlib/helper/PlainTextAttribute.java b/src/main/java/com/movisens/smartgattlib/helper/PlainTextAttribute.java new file mode 100644 index 0000000..c2c5cb8 --- /dev/null +++ b/src/main/java/com/movisens/smartgattlib/helper/PlainTextAttribute.java @@ -0,0 +1,11 @@ +package com.movisens.smartgattlib.helper; + +/** + * Attributes that implements the PlainTextAttribute interface will not be encrypted. + * + * @author ulrich.grossmann + * + */ +public interface PlainTextAttribute +{ +} diff --git a/src/main/java/com/movisens/smartgattlib/helper/Service.java b/src/main/java/com/movisens/smartgattlib/helper/Service.java new file mode 100644 index 0000000..1fb5096 --- /dev/null +++ b/src/main/java/com/movisens/smartgattlib/helper/Service.java @@ -0,0 +1,11 @@ +package com.movisens.smartgattlib.helper; + +public class Service extends UuidObject +{ + + public Service(String uuid, String name) + { + super(uuid, name); + } + +} diff --git a/src/main/java/com/movisens/smartgattlib/helper/TimeZoneUtil.java b/src/main/java/com/movisens/smartgattlib/helper/TimeZoneUtil.java new file mode 100644 index 0000000..382ccda --- /dev/null +++ b/src/main/java/com/movisens/smartgattlib/helper/TimeZoneUtil.java @@ -0,0 +1,51 @@ +package com.movisens.smartgattlib.helper; + +import java.util.HashMap; +import java.util.Map.Entry; + +public class TimeZoneUtil +{ + + private static HashMap getTransformMap() + { + HashMap map = new HashMap(); + map.put("ARG", "America/Argentina"); + map.put("AM", "America"); + map.put("EU", "Europe"); + map.put("AU", "Australia"); + map.put("ANT", "Antarctica"); + map.put("ND", "North_Dakota"); + map.put("KY", "Kentucky"); + map.put("/IN", "/Indiana"); + map.put("ATC", "Atlantic"); + map.put("AFR", "Africa"); + map.put("PFC", "Pacific"); + return map; + } + + public static String toLongTimeZone(String timeZoneString) + { + String id = timeZoneString; + HashMap map = getTransformMap(); + + for (Entry e : map.entrySet()) + { + id = id.replaceAll(e.getKey(), e.getValue()); + } + + return id; + } + + public static String toShortTimeZone(String timeZoneString) + { + String id = timeZoneString; + HashMap map = getTransformMap(); + + for (Entry e : map.entrySet()) + { + id = id.replaceAll(e.getValue(), e.getKey()); + } + + return id; + } +} diff --git a/src/main/java/com/movisens/smartgattlib/helper/UuidObject.java b/src/main/java/com/movisens/smartgattlib/helper/UuidObject.java new file mode 100644 index 0000000..815c3ee --- /dev/null +++ b/src/main/java/com/movisens/smartgattlib/helper/UuidObject.java @@ -0,0 +1,49 @@ +package com.movisens.smartgattlib.helper; + +import java.util.UUID; + +public class UuidObject +{ + + private static final long leastSigUuidBits = 0x800000805f9b34fbL; + + private UUID uuid; + + private String name; + + public UuidObject(String uuidString, String name) + { + this.uuid = stringToUuid(uuidString); + this.name = name; + } + + public UUID getUuid() + { + return uuid; + } + + public String getName() + { + return name; + } + + public static UUID stringToUuid(String uuidString) + { + UUID uuid; + if (uuidString.length() == 4) + { + /* it is a short form uuid */ + uuid = new UUID((Long.parseLong(uuidString, 16) << 32) | 0x1000, leastSigUuidBits); + } + else + { + uuid = UUID.fromString(uuidString); + } + + return uuid; + } + + public boolean equals(UUID uuid) { + return this.getUuid().equals(uuid); + } +} diff --git a/src/main/java/com/movisens/smartgattlib/helper/UuidObjectMap.java b/src/main/java/com/movisens/smartgattlib/helper/UuidObjectMap.java new file mode 100644 index 0000000..bf2f1a1 --- /dev/null +++ b/src/main/java/com/movisens/smartgattlib/helper/UuidObjectMap.java @@ -0,0 +1,26 @@ +package com.movisens.smartgattlib.helper; + +import java.util.Collection; +import java.util.HashMap; +import java.util.UUID; + +public class UuidObjectMap +{ + + private HashMap map = new HashMap(); + + public void put(T uuidObject) + { + map.put(uuidObject.getUuid(), uuidObject); + } + + public T get(UUID uuid) + { + return map.get(uuid); + } + + public Collection getValues() + { + return map.values(); + } +} diff --git a/src/main/java/com/movisens/smartgattlib/security/AesUtil.java b/src/main/java/com/movisens/smartgattlib/security/AesUtil.java new file mode 100644 index 0000000..c85be72 --- /dev/null +++ b/src/main/java/com/movisens/smartgattlib/security/AesUtil.java @@ -0,0 +1,167 @@ +package com.movisens.smartgattlib.security; + +import java.nio.charset.StandardCharsets; +import java.security.spec.KeySpec; +import java.util.Arrays; + +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.SecretKeySpec; + +public class AesUtil +{ + + public static void main(String[] args) { + + byte[] keydata = {1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6}; + + SecretKey key = createAesKey(keydata); + byte[] chiperText = encrypt("1234567890123456".getBytes(StandardCharsets.UTF_8), key); + + for(int i=0;i 16 && input.length < 32) + { + return encryptCtsTail(input, key); + } + else + { + throw new RuntimeException("input len not supported"); + } + } + + public static byte[] decrypt(byte[] input, SecretKey key) + { + if (input.length % 16 == 0) + { + return decryptBlocks(input, key); + } + else if (input.length > 16 && input.length < 32) + { + return decryptCtsTail(input, key); + } + else + { + throw new RuntimeException("input len not supported"); + } + } + + public static byte[] encryptCtsTail(byte[] plainText, SecretKey key) + { + // ciphertext stealing (CTS) + + // input.length 17 .. 31 + + byte[] b1 = Arrays.copyOfRange(plainText, 0, 16); + byte[] c1 = encryptBlocks(b1, key); + + byte[] b2 = new byte[16]; + System.arraycopy(plainText, 16, b2, 0, plainText.length - 16); + System.arraycopy(c1, plainText.length - 16, b2, plainText.length - 16, 32 - plainText.length); + byte[] c2 = encryptBlocks(b2, key); + + byte[] cipherText = new byte[plainText.length]; + System.arraycopy(c1, 0, cipherText, 0, plainText.length - 16); + System.arraycopy(c2, 0, cipherText, plainText.length - 16, 16); + + return cipherText; + } + + public static byte[] decryptCtsTail(byte[] cipherText, SecretKey key) + { + // ciphertext stealing (CTS) + + // input.length 17 .. 31 + + byte[] b1 = Arrays.copyOfRange(cipherText, cipherText.length - 16, cipherText.length); + byte[] c1 = decryptBlocks(b1, key); + + byte[] b2 = new byte[16]; + System.arraycopy(cipherText, 0, b2, 0, cipherText.length - 16); + System.arraycopy(c1, cipherText.length - 16, b2, cipherText.length - 16, 32 - cipherText.length); + byte[] c2 = decryptBlocks(b2, key); + + byte[] plainText = new byte[cipherText.length]; + System.arraycopy(c1, 0, plainText, 16, cipherText.length - 16); + System.arraycopy(c2, 0, plainText, 0, 16); + + return plainText; + } + + public static byte[] encryptBlocks(byte[] input, SecretKey key) + { + try + { + Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding"); + cipher.init(Cipher.ENCRYPT_MODE, key); + return cipher.doFinal(input); + } + catch (Throwable e) + { + throw new RuntimeException(e.getMessage()); + } + } + + public static byte[] decryptBlocks(byte[] cipherText, SecretKey key) + { + try + { + Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding"); + cipher.init(Cipher.DECRYPT_MODE, key); + return cipher.doFinal(cipherText); + } + catch (Throwable e) + { + throw new RuntimeException(e.getMessage()); + } + } + +} diff --git a/src/main/java/com/movisens/smartgattlib/security/CryptoManager.java b/src/main/java/com/movisens/smartgattlib/security/CryptoManager.java new file mode 100644 index 0000000..2c9fb3f --- /dev/null +++ b/src/main/java/com/movisens/smartgattlib/security/CryptoManager.java @@ -0,0 +1,53 @@ +package com.movisens.smartgattlib.security; + +import javax.crypto.SecretKey; + +public class CryptoManager +{ + + private SecretKey secretKey = null; + + public void setKey(byte[] secretKey) + { + this.secretKey = AesUtil.createAesKey(secretKey); + } + + public void initialize() + { + disableEncryption(); + } + + public void disableEncryption() + { + secretKey = null; + } + + public boolean encryptionEnabled() + { + return secretKey != null; + } + + public byte[] processBeforeSend(byte[] data) + { + if (secretKey != null) + { + return AesUtil.encrypt(data, secretKey); + } + else + { + return data; + } + } + + public byte[] processAfterReceive(byte[] data) + { + if (secretKey != null) + { + return AesUtil.decrypt(data, secretKey); + } + else + { + return data; + } + } +} diff --git a/src/main/java/com/movisens/smartgattlib/security/KeyGenerator.java b/src/main/java/com/movisens/smartgattlib/security/KeyGenerator.java new file mode 100644 index 0000000..fc8e9d4 --- /dev/null +++ b/src/main/java/com/movisens/smartgattlib/security/KeyGenerator.java @@ -0,0 +1,21 @@ +package com.movisens.smartgattlib.security; + +import javax.crypto.SecretKey; + +import com.movisens.smartgattlib.helper.GattByteBuffer; + +public class KeyGenerator +{ + public static long[] createKey(String password) { + + SecretKey key = AesUtil.createAesKey(password); + GattByteBuffer bb = GattByteBuffer.wrap(key.getEncoded()); + + long[] result = new long[2]; + result[0] = bb.getInt64(); + result[1] = bb.getInt64(); + + return result; + } + +} diff --git a/src/test/java/BatteryLevelTest.java b/src/test/java/BatteryLevelTest.java index 8e6bd04..87de558 100644 --- a/src/test/java/BatteryLevelTest.java +++ b/src/test/java/BatteryLevelTest.java @@ -1,6 +1,5 @@ import com.movisens.smartgattlib.GattUtils; -import com.movisens.smartgattlib.characteristics.BatteryLevel; -import com.movisens.smartgattlib.characteristics.HeartRateMeasurement; +import com.movisens.smartgattlib.attributes.BatteryLevel; import org.junit.Test; import static org.junit.Assert.assertTrue; @@ -9,6 +8,6 @@ public class BatteryLevelTest { @Test public void testBatteryLevel() { byte[] testValue = GattUtils.hexStringToByteArray("2C"); BatteryLevel batteryLevel = new BatteryLevel(testValue); - assertTrue("Battery level should be 44", batteryLevel.getBatteryLevel() == 44); + assertTrue("Battery level should be 44", batteryLevel.getLevel() == 44); } } diff --git a/src/test/java/CyclingSpeedCadenceMeasurementTest.java b/src/test/java/CyclingSpeedCadenceMeasurementTest.java index 21af9ff..0b6cd9a 100644 --- a/src/test/java/CyclingSpeedCadenceMeasurementTest.java +++ b/src/test/java/CyclingSpeedCadenceMeasurementTest.java @@ -1,5 +1,5 @@ import com.movisens.smartgattlib.GattUtils; -import com.movisens.smartgattlib.characteristics.CyclingSpeedCadenceMeasurement; +import com.movisens.smartgattlib.attributes.CscMeasurement; import org.junit.Test; @@ -10,12 +10,12 @@ public class CyclingSpeedCadenceMeasurementTest { @Test public void testCCM() { byte[] testValue = GattUtils.hexStringToByteArray("032D060000A3A9900A289F"); - CyclingSpeedCadenceMeasurement ccm = new CyclingSpeedCadenceMeasurement(testValue); + CscMeasurement ccm = new CscMeasurement(testValue); assertTrue("Wheel rev should be present", ccm.isWheelRevPresent()); assertTrue("Crank rev should be present", ccm.isCrankRevPresent()); assertTrue("Cumulative crank revolutions should be 2704", ccm.getCumulativeCrankRevolutions() == 2704); - assertTrue("Last crank event time should be 0", ccm.getLastCrankEventTime() == 40744); + assertTrue("Last crank event time should be 0", ccm.getCrankEventTime() == 40744); assertTrue("Cumulative wheel revolutions should be 1581", ccm.getCumulativeWheelRevolutions() == 1581); - assertTrue("Last wheel even time should be 43427", ccm.getLastWheelEventTime() == 43427); + assertTrue("Last wheel even time should be 43427", ccm.getWheelEventTime() == 43427); } } diff --git a/src/test/java/Example.java b/src/test/java/Example.java new file mode 100644 index 0000000..42f29f1 --- /dev/null +++ b/src/test/java/Example.java @@ -0,0 +1,53 @@ +import java.util.UUID; + +import com.movisens.smartgattlib.Characteristics; +import com.movisens.smartgattlib.Services; +import com.movisens.smartgattlib.attributes.DefaultAttribute; +import com.movisens.smartgattlib.attributes.HeartRateMeasurement; +import com.movisens.smartgattlib.attributes.Weight; +import com.movisens.smartgattlib.helper.AbstractAttribute; +import com.movisens.smartgattlib.security.CryptoManager; + +public class Example { + + public static void main(String[] args) { + // onConnected + // TODO: iterate over available services + UUID serviceUuid = null;// service.getUuid(); + if (Services.HEART_RATE.equals(serviceUuid)) { + + // TODO: iterate over characteristics + UUID characteristicUuid = null;// characteristic.getUuid(); + if (Characteristics.HEART_RATE_MEASUREMENT.equals(characteristicUuid)) { + // TODO: Enable notification e.g. for Android API 18: + // BluetoothGattDescriptor descriptor = characteristic.getDescriptor(Descriptor.CLIENT_CHARACTERISTIC_CONFIGURATION); + // descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); + // mBluetoothGatt.writeDescriptor(descriptor); + } + } else { + System.out.println("Found unused Service: " + Services.lookup(serviceUuid)); + } + + // onCharacteristicChanged + UUID uuid = null;// characteristic.getUuid(); + byte[] data = null;// characteristic.getValue(); + + CryptoManager cryptoManager = new CryptoManager(); + + AbstractAttribute a = Characteristics.lookup(uuid).createAttribute(cryptoManager, data); + if (a instanceof HeartRateMeasurement) { + HeartRateMeasurement heartRateMeasurement = ((HeartRateMeasurement) a); + heartRateMeasurement.getHr(); + heartRateMeasurement.getEe(); + } else if (a instanceof DefaultAttribute) { + System.err.println("characteristic for " + uuid + " is unknown"); + } else { + System.out.println("unused characteristic " + a.getCharacteristic().getName()); + } + + // write Attribute + @SuppressWarnings("unused") + AbstractAttribute aa = new Weight(12.3); + // TODO: Write aa.getBytes() to aa.getCharacteristic().getUuid(); + } +} diff --git a/src/test/java/HeartRateMeasurementTest.java b/src/test/java/HeartRateMeasurementTest.java index 21762ff..0b5e587 100644 --- a/src/test/java/HeartRateMeasurementTest.java +++ b/src/test/java/HeartRateMeasurementTest.java @@ -1,5 +1,5 @@ import com.movisens.smartgattlib.GattUtils; -import com.movisens.smartgattlib.characteristics.HeartRateMeasurement; +import com.movisens.smartgattlib.attributes.HeartRateMeasurement; import org.junit.Test; import static org.junit.Assert.*; @@ -10,7 +10,7 @@ public class HeartRateMeasurementTest { assertTrue("HR should be 72", hrm.getHr() == 72); assertTrue("Sensor is worn", hrm.getSensorWorn() == HeartRateMeasurement.SensorWorn.WORN); assertTrue("EE should not be available", hrm.getEe() == -1); - assertTrue("2 RR intervals should be available", hrm.getRrInterval().size() == 2); - assertTrue("RR intervals should be correct", hrm.getRrInterval().get(0) == 0.33203125 && hrm.getRrInterval().get(1) == 0.73046875); + assertTrue("2 RR intervals should be available", hrm.getRrIntervals().size() == 2); + assertTrue("RR intervals should be correct", hrm.getRrIntervals().get(0) == 0.33203125 && hrm.getRrIntervals().get(1) == 0.73046875); } } diff --git a/src/test/java/WeightTest.java b/src/test/java/WeightTest.java new file mode 100644 index 0000000..1ad9644 --- /dev/null +++ b/src/test/java/WeightTest.java @@ -0,0 +1,26 @@ +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.movisens.smartgattlib.attributes.Weight; +import com.movisens.smartgattlib.helper.GattByteBuffer; + +/** + * Created by robert.zetzsche on 17.05.2017. + */ +public class WeightTest { + @Test + public void testWeight() { + Float weightFloat = 12.5f; + byte[] bytes = GattByteBuffer.allocate(2).putUint16(Math.round(weightFloat * 200)).array(); + Weight weight = new Weight(weightFloat.doubleValue()); + Weight weightBytes = new Weight(bytes); + assertEquals(weight.getWeight(), weightFloat, 0); + assertEquals(weightBytes.getWeight(), weightFloat.doubleValue(), 0); + assertEquals(weightBytes.getWeight(), weight.getWeight()); + assertArrayEquals(weight.getBytes(), bytes); + assertArrayEquals(weightBytes.getBytes(), bytes); + assertArrayEquals(weight.getBytes(), weightBytes.getBytes()); + } +} diff --git a/src/test/java/com/movisens/smartgattlib/helper/GattByteBufferTest.java b/src/test/java/com/movisens/smartgattlib/helper/GattByteBufferTest.java new file mode 100644 index 0000000..bc20065 --- /dev/null +++ b/src/test/java/com/movisens/smartgattlib/helper/GattByteBufferTest.java @@ -0,0 +1,29 @@ +package com.movisens.smartgattlib.helper; + +import static org.junit.Assert.assertTrue; + +import java.time.ZoneId; +import java.util.Set; + +import org.junit.Test; + + +public class GattByteBufferTest +{ + + @Test + public void testPutTimeZone() + { + Set zIds = ZoneId.getAvailableZoneIds(); + for (String zId : zIds) + { + GattByteBuffer bb = GattByteBuffer.allocate(20); + + bb.putTimezone(zId); + bb.rewind(); + String gtz = bb.getTimezone(); + assertTrue(gtz.equals(zId)); + } + } + +} diff --git a/src/test/java/com/movisens/smartgattlib/security/AesUtilTest.java b/src/test/java/com/movisens/smartgattlib/security/AesUtilTest.java new file mode 100644 index 0000000..7e550ac --- /dev/null +++ b/src/test/java/com/movisens/smartgattlib/security/AesUtilTest.java @@ -0,0 +1,79 @@ +package com.movisens.smartgattlib.security; + +import static org.junit.Assert.assertEquals; + +import javax.crypto.SecretKey; + +import org.junit.Test; + + +public class AesUtilTest +{ + static SecretKey key = AesUtil.createAesKey("secret"); + + @Test + public void testSmallBlock() + { + String plainText = "abcdefgh"; + + byte[] ciperText = AesUtil.encrypt(plainText.getBytes(), key); + assertEquals(16, ciperText.length); + + byte[] resultText = AesUtil.decrypt(ciperText, key); + String resultString = new String(resultText, 0, plainText.length()); + assertEquals(plainText, resultString); + } + + @Test + public void testMultibleOf16k() + { + String plainText = "123456781234567812345678123456781234567812345678"; + + byte[] ciperText = AesUtil.encrypt(plainText.getBytes(), key); + assertEquals(plainText.length(), ciperText.length); + + byte[] resultText = AesUtil.decrypt(ciperText, key); + String resultString = new String(resultText, 0, plainText.length()); + assertEquals(plainText, resultString); + } + + @Test + public void testLen17() + { + String plainText = "12345678123456781"; + + byte[] ciperText = AesUtil.encrypt(plainText.getBytes(), key); + assertEquals(plainText.length(), ciperText.length); + + byte[] resultText = AesUtil.decrypt(ciperText, key); + String resultString = new String(resultText, 0, plainText.length()); + assertEquals(plainText, resultString); + } + + @Test + public void testLen20() + { + String plainText = "123456781234567812"; + + byte[] ciperText = AesUtil.encrypt(plainText.getBytes(), key); + assertEquals(plainText.length(), ciperText.length); + + byte[] resultText = AesUtil.decrypt(ciperText, key); + String resultString = new String(resultText, 0, plainText.length()); + assertEquals(plainText, resultString); + } + + @Test + public void testLen31() + { + String plainText = "1234567812345678123456781234567"; + + byte[] ciperText = AesUtil.encrypt(plainText.getBytes(), key); + assertEquals(plainText.length(), ciperText.length); + + byte[] resultText = AesUtil.decrypt(ciperText, key); + String resultString = new String(resultText, 0, plainText.length()); + assertEquals(plainText, resultString); + } + +}