mediaProfiles) {
90 |
91 | }
92 | });
93 | ```
94 |
95 | ### Media Stream URI
96 | Returns a raw media stream URI that remains valid indefinitely even if the profile is changed.
97 |
98 | ```java
99 | onvifManager.getMediaStreamURI(device, mediaProfiles.get(0), new OnvifMediaStreamURIListener() {
100 | @Override
101 | public void onMediaStreamURIReceived(@Nonnull OnvifDevice device,
102 | @Nonnull OnvifMediaProfile profile, @Nonnull String uri) {
103 |
104 | }
105 | });
106 | ```
107 |
108 | ## UPnP
109 | ---
110 |
111 | With the ```UPnPManager``` it is possible to retrieve device information from a locally connected UPnP device. A ```UPnPDevice``` can be created manually or discovered from the ```DiscoveryManager``` using ```discovery.discover(DiscoveryMode.UPNP)```
112 |
113 | ```java
114 | UPnPDevice device = new UPnPDevice("192.168.0.160");
115 | device.setLocation("http://192.168.0.160:49152/rootdesc1.xml");
116 | UPnPManager uPnPManager = new UPnPManager();
117 | uPnPManager.getDeviceInformation(device, new UPnPDeviceInformationListener() {
118 | @Override
119 | public void onDeviceInformationReceived(@Nonnull UPnPDevice device,
120 | @Nonnull UPnPDeviceInformation information) {
121 | Log.i(TAG, device.getHostName() + ": " + information.getFriendlyName());
122 | }
123 | @Override
124 | public void onError(@Nonnull UPnPDevice onvifDevice, int errorCode, String errorMessage) {
125 | Log.e(TAG, "Error: " + errorMessage);
126 | }
127 | });
128 | ```
129 |
130 | ## Custom requests
131 | ---
132 |
133 | It is possible to implement your custom ONVIF request by creating a new class and implementing the ```OnvifRequest``` interface and overriding the ```getXml()``` and ```getType()``` methods.
134 |
135 | ```java
136 | public class PTZRequest implements OnvifRequest {
137 | @Override
138 | public String getXml() {
139 | return "" +
140 | "false" +
141 | "";
142 | }
143 | @Override
144 | public OnvifType getType() {
145 | return OnvifType.CUSTOM;
146 | }
147 | }
148 | ```
149 |
150 | and send it to the appropriate ```OnvifDevice```:
151 |
152 | ```java
153 | onvifManager.sendOnvifRequest(device, new PTZRequest());
154 | ```
155 |
156 | Use the ```OnvifResponseListener``` to receive responses from your custom requests.
157 |
158 | ## Android
159 | ---
160 | In order to receive multicasts packets on your Android device, you'll have to acquire a lock on your WifiManager before making a discovery. Make sure to release the lock once the discovery is completed. More information can be found here: https://developer.android.com/reference/android/net/wifi/WifiManager.MulticastLock
161 |
162 | ```java
163 | private void lockMulticast() {
164 | WifiManager wifi = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
165 | if (wifi == null)
166 | return;
167 |
168 | WifiManager.MulticastLock lock = wifi.createMulticastLock("ONVIF");
169 | lock.acquire();
170 | }
171 | ```
172 |
173 | Download
174 | --------
175 |
176 | Download [the latest JAR][2] or grab via Maven:
177 | ```xml
178 |
179 | be.teletask.onvif
180 | onvif
181 | 1.0.0
182 |
183 | ```
184 | or Gradle:
185 | ```groovy
186 | compile 'be.teletask.onvif:onvif:1.0.0'
187 | ```
188 |
189 | ## Todos
190 |
191 | - Implementation ONVIF version management
192 | - Implementation PTZ
193 |
194 | ## Pull Requests
195 | ---
196 | Feel free to send pull requests.
197 |
198 | License
199 | =======
200 |
201 | Copyright 2018 TELETASK BVBA.
202 |
203 | Licensed under the Apache License, Version 2.0 (the "License");
204 | you may not use this file except in compliance with the License.
205 | You may obtain a copy of the License at
206 |
207 | http://www.apache.org/licenses/LICENSE-2.0
208 |
209 | Unless required by applicable law or agreed to in writing, software
210 | distributed under the License is distributed on an "AS IS" BASIS,
211 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
212 | See the License for the specific language governing permissions and
213 | limitations under the License.
214 |
215 | [2]: https://bintray.com/tomasverhelst/ONVIF-Java/ONVIF-Java/1.0.0#files/be/teletask/onvif/onvif/1.0.0
216 |
217 |
--------------------------------------------------------------------------------
/lib/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.gitignore.io/api/java,android,intellij
3 |
4 | ### Android ###
5 | # Built application files
6 | *.apk
7 | *.ap_
8 |
9 | # Files for the ART/Dalvik VM
10 | *.dex
11 |
12 | # Java class files
13 | *.class
14 |
15 | # Generated files
16 | bin/
17 | gen/
18 | out/
19 |
20 | # Gradle files
21 | .gradle/
22 | build/
23 |
24 | # Local configuration file (sdk path, etc)
25 | local.properties
26 |
27 | # Proguard folder generated by Eclipse
28 | proguard/
29 |
30 | # Log Files
31 | *.log
32 |
33 | # Android Studio Navigation editor temp files
34 | .navigation/
35 |
36 | # Android Studio captures folder
37 | captures/
38 |
39 | # IntelliJ
40 | *.iml
41 | .idea
42 | .idea/workspace.xml
43 | .idea/tasks.xml
44 | .idea/gradle.xml
45 | .idea/assetWizardSettings.xml
46 | .idea/dictionaries
47 | .idea/libraries
48 | .idea/caches
49 |
50 | # Keystore files
51 | # Uncomment the following line if you do not want to check your keystore files in.
52 | #*.jks
53 |
54 | # External native build folder generated in Android Studio 2.2 and later
55 | .externalNativeBuild
56 |
57 | # Google Services (e.g. APIs or Firebase)
58 | google-services.json
59 |
60 | # Freeline
61 | freeline.py
62 | freeline/
63 | freeline_project_description.json
64 |
65 | # fastlane
66 | fastlane/report.xml
67 | fastlane/Preview.html
68 | fastlane/screenshots
69 | fastlane/test_output
70 | fastlane/readme.md
71 |
72 | ### Android Patch ###
73 | gen-external-apklibs
74 |
75 | ### Intellij ###
76 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
77 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
78 |
79 | # User-specific stuff
80 | .idea/**/workspace.xml
81 | .idea/**/tasks.xml
82 | .idea/**/usage.statistics.xml
83 | .idea/**/dictionaries
84 | .idea/**/shelf
85 |
86 | # Generated files
87 | .idea/**/contentModel.xml
88 |
89 | # Sensitive or high-churn files
90 | .idea/**/dataSources/
91 | .idea/**/dataSources.ids
92 | .idea/**/dataSources.local.xml
93 | .idea/**/sqlDataSources.xml
94 | .idea/**/dynamic.xml
95 | .idea/**/uiDesigner.xml
96 | .idea/**/dbnavigator.xml
97 |
98 | # Gradle
99 | .idea/**/gradle.xml
100 | .idea/**/libraries
101 |
102 | # Gradle and Maven with auto-import
103 | # When using Gradle or Maven with auto-import, you should exclude module files,
104 | # since they will be recreated, and may cause churn. Uncomment if using
105 | # auto-import.
106 | # .idea/modules.xml
107 | # .idea/*.iml
108 | # .idea/modules
109 |
110 | # CMake
111 | cmake-build-*/
112 |
113 | # Mongo Explorer plugin
114 | .idea/**/mongoSettings.xml
115 |
116 | # File-based project format
117 | *.iws
118 |
119 | # IntelliJ
120 |
121 | # mpeltonen/sbt-idea plugin
122 | .idea_modules/
123 |
124 | # JIRA plugin
125 | atlassian-ide-plugin.xml
126 |
127 | # Cursive Clojure plugin
128 | .idea/replstate.xml
129 |
130 | # Crashlytics plugin (for Android Studio and IntelliJ)
131 | com_crashlytics_export_strings.xml
132 | crashlytics.properties
133 | crashlytics-build.properties
134 | fabric.properties
135 |
136 | # Editor-based Rest Client
137 | .idea/httpRequests
138 |
139 | ### Intellij Patch ###
140 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
141 |
142 | # *.iml
143 | # modules.xml
144 | # .idea/misc.xml
145 | # *.ipr
146 |
147 | # Sonarlint plugin
148 | .idea/sonarlint
149 |
150 | ### Java ###
151 | # Compiled class file
152 |
153 | # Log file
154 |
155 | # BlueJ files
156 | *.ctxt
157 |
158 | # Mobile Tools for Java (J2ME)
159 | .mtj.tmp/
160 |
161 | # Package Files #
162 | *.jar
163 | *.war
164 | *.nar
165 | *.ear
166 | *.zip
167 | *.tar.gz
168 | *.rar
169 |
170 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
171 | hs_err_pid*
172 |
173 |
174 | # End of https://www.gitignore.io/api/java,android,intellij
--------------------------------------------------------------------------------
/lib/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | jcenter()
4 | }
5 | dependencies {
6 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
7 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
8 | }
9 | }
10 |
11 | plugins {
12 | id 'java'
13 | }
14 |
15 | group 'be.teletask.onvif'
16 | version '1.0.0'
17 |
18 | sourceCompatibility = 1.8
19 |
20 | if (JavaVersion.current().isJava8Compatible()) {
21 | allprojects {
22 | tasks.withType(Javadoc) {
23 | options.addStringOption('Xdoclint:none', '-quiet')
24 | }
25 | }
26 | }
27 |
28 | repositories {
29 | mavenCentral()
30 | jcenter()
31 | }
32 |
33 | dependencies {
34 | testCompile group: 'junit', name: 'junit', version: '4.12'
35 |
36 | //Annotations
37 | compile group: 'org.jetbrains', name: 'annotations', version: '15.0'
38 |
39 | //XML parser
40 | compile group: 'net.sf.kxml', name: 'kxml2', version: '2.3.0'
41 |
42 | //OkHttp
43 | compile 'com.squareup.okhttp3:okhttp:3.11.0'
44 |
45 | //OkHttp Digest
46 | compile 'com.burgstaller:okhttp-digest:1.18'
47 | }
48 |
49 | ext {
50 | bintrayRepo = 'ONVIF-Java'
51 | bintrayName = 'ONVIF-Java'
52 |
53 | publishedGroupId = 'be.teletask.onvif'
54 | libraryName = 'ONVIF-Java'
55 | artifact = 'onvif'
56 |
57 | libraryDescription = 'A Java client library to discover, control and manage ONVIF-supported devices.'
58 |
59 | siteUrl = 'https://github.com/RootSoft/ONVIF-Java'
60 | gitUrl = 'https://github.com/RootSoft/ONVIF-Java.git'
61 |
62 | libraryVersion = '1.0.2'
63 |
64 | developerId = 'tomasverhelst'
65 | developerName = 'Tomas Verhelst'
66 | developerEmail = 'tve@teletask.be'
67 |
68 | licenseName = 'The Apache Software License, Version 2.0'
69 | licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
70 | allLicenses = ["Apache-2.0"]
71 | }
72 |
73 | apply plugin: 'com.github.dcendents.android-maven'
74 | apply plugin: 'com.jfrog.bintray'
75 |
76 | group = publishedGroupId
77 | version = libraryVersion
78 |
79 | install {
80 | repositories.mavenInstaller {
81 | pom.project {
82 | packaging 'jar'
83 | groupId publishedGroupId
84 | artifactId artifact
85 |
86 | name libraryName
87 | description libraryDescription
88 | url siteUrl
89 |
90 | licenses {
91 | license {
92 | name licenseName
93 | url licenseUrl
94 | }
95 | }
96 | developers {
97 | developer {
98 | id developerId
99 | name developerName
100 | email developerEmail
101 | }
102 | }
103 | scm {
104 | connection gitUrl
105 | developerConnection gitUrl
106 | url siteUrl
107 | }
108 | }
109 | }
110 | }
111 |
112 | task sourcesJar(type: Jar) {
113 | classifier = 'sources'
114 | from sourceSets.main.java.srcDirs
115 | }
116 |
117 | task javadocJar(type: Jar, dependsOn: javadoc) {
118 | classifier = 'javadoc'
119 | from javadoc.destinationDir
120 | }
121 |
122 | artifacts {
123 | archives javadocJar
124 | archives sourcesJar
125 | }
126 |
127 | Properties properties = new Properties()
128 | properties.load(project.rootProject.file('local.properties').newDataInputStream())
129 |
130 | bintray {
131 | user = properties.getProperty("bintray.user")
132 | key = properties.getProperty("bintray.apikey")
133 |
134 | configurations = ['archives']
135 | pkg {
136 | repo = bintrayRepo
137 | name = bintrayName
138 | desc = libraryDescription
139 | websiteUrl = siteUrl
140 | vcsUrl = gitUrl
141 | licenses = allLicenses
142 | dryRun = false
143 | publish = true
144 | override = false
145 | publicDownloadNumbers = true
146 | version {
147 | desc = libraryDescription
148 | }
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/lib/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Sep 07 13:33:20 CEST 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-all.zip
7 |
--------------------------------------------------------------------------------
/lib/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/lib/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/lib/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'onvif'
2 |
3 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/DiscoveryManager.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif;
2 |
3 | import be.teletask.onvif.listeners.DiscoveryListener;
4 |
5 |
6 | import java.net.InetAddress;
7 | import java.util.List;
8 |
9 | /**
10 | * Created by Tomas Verhelst on 06/09/2018.
11 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
12 | */
13 | public class DiscoveryManager {
14 |
15 | //Constants
16 | public static final String TAG = DiscoveryManager.class.getSimpleName();
17 |
18 | //Attributes
19 | private OnvifDiscovery discovery;
20 |
21 | //Constructors
22 |
23 | public DiscoveryManager() {
24 | discovery = new OnvifDiscovery();
25 | }
26 |
27 | //Methods
28 |
29 | /**
30 | * Discovers a list of ONVIF-compatible device on the LAN.
31 | *
32 | * An ONVIF device in discoverable mode sends multicast Hello messages once connected to the
33 | * network or sends its Status changes according to [WS-Discovery]. In addition it always listens
34 | * for Probe and Resolve messages and sends responses accordingly.
35 | * A device in nondiscoverable will not listen to [WS-Discovery] messages or send such messages.
36 | *
37 | * @param discoveryListener
38 | */
39 | public void discover(DiscoveryListener discoveryListener) {
40 | discover(DiscoveryMode.ONVIF, discoveryListener);
41 | }
42 |
43 | /**
44 | * Discovers a list of network devices on the LAN using the specified discovery mode.
45 | *
46 | * The discovery protocol used is Simple Service Discovery Protocol (SSDP).
47 | * When a device is added to the network, SSDP allows that device to advertise its services
48 | * to control points on the network. This is achieved by sending SSDP alive messages.
49 | *
50 | * When a control point is added to the network, SSDP allows that control point to actively
51 | * search for devices of interest on the network or listen passively to the SSDP alive messages of device.
52 | *
53 | * @param discoveryListener
54 | */
55 | public void discover(DiscoveryMode mode, DiscoveryListener discoveryListener) {
56 | discovery.probe(mode, discoveryListener);
57 | }
58 |
59 | /**
60 | * Gets a list of interface addresses on this device.
61 | *
62 | * @return
63 | */
64 | public List getInterfaceAddresses() {
65 | return discovery.getInterfaceAddresses();
66 | }
67 |
68 | /**
69 | * Gets a list of all broadcast addresses on this device.
70 | *
71 | * @return
72 | */
73 | public List getBroadcastAddresses() {
74 | return discovery.getBroadcastAddresses();
75 | }
76 |
77 | /**
78 | * Gets the local IP address of this device.
79 | *
80 | * @return
81 | */
82 | public String getLocalIpAddress() {
83 | return discovery.getLocalIpAddress();
84 | }
85 |
86 | //Properties
87 |
88 | /**
89 | * Gets the timeout (in milliseconds) to discover devices.
90 | * Defaults to 10 seconds.
91 | *
92 | * @return the timeout in milliseconds.
93 | */
94 | public int getDiscoveryTimeout() {
95 | return discovery.getDiscoveryTimeout();
96 | }
97 |
98 | /**
99 | * Sets the timeout in milliseconds to discover devices.
100 | * Defaults to 10 seconds
101 | *
102 | * @param timeoutMs the timeout in milliseconds
103 | */
104 | public void setDiscoveryTimeout(int timeoutMs) {
105 | discovery.setDiscoveryTimeout(timeoutMs);
106 | }
107 |
108 | /**
109 | * Gets the discovery mode.
110 | * Defaults to ONVIF
111 | *
112 | * @return the discovery mode
113 | */
114 | public DiscoveryMode getDiscoveryMode() {
115 | return discovery.getDiscoveryMode();
116 | }
117 |
118 | /**
119 | * Sets the discovery mode.
120 | */
121 | public void setDiscoveryMode(DiscoveryMode mode) {
122 | discovery.setDiscoveryMode(mode);
123 | }
124 |
125 | }
126 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/DiscoveryMode.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif;
2 |
3 | /**
4 | * Created by Tomas Verhelst on 05/09/2018.
5 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
6 | */
7 | public enum DiscoveryMode {
8 | ONVIF(3702),
9 | UPNP(1900);
10 |
11 | public final int port;
12 |
13 | DiscoveryMode(int port) {
14 | this.port = port;
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/DiscoveryThread.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif;
2 |
3 | import be.teletask.onvif.listeners.DiscoveryCallback;
4 | import be.teletask.onvif.parsers.DiscoveryParser;
5 | import be.teletask.onvif.responses.OnvifResponse;
6 |
7 | import java.io.IOException;
8 | import java.net.DatagramPacket;
9 | import java.net.DatagramSocket;
10 |
11 | /**
12 | * Created by Tomas Verhelst on 05/09/2018.
13 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
14 | */
15 | public class DiscoveryThread extends Thread {
16 |
17 | //Constants
18 | public static final String TAG = DiscoveryThread.class.getSimpleName();
19 |
20 | //Attributes
21 | private DatagramSocket server;
22 | private int timeout;
23 | private DiscoveryParser parser;
24 | private DiscoveryCallback callback;
25 |
26 | //Constructors
27 | DiscoveryThread(DatagramSocket server, int timeout, DiscoveryMode mode, DiscoveryCallback callback) {
28 | super();
29 | this.server = server;
30 | this.timeout = timeout;
31 | this.callback = callback;
32 | parser = new DiscoveryParser(mode);
33 | }
34 |
35 | @Override
36 | public void run() {
37 | try {
38 | boolean started = false;
39 | DatagramPacket packet = new DatagramPacket(new byte[4096], 4096);
40 | server.setSoTimeout(timeout);
41 | long timerStarted = System.currentTimeMillis();
42 | while (System.currentTimeMillis() - timerStarted < timeout) {
43 | if (!started) {
44 | callback.onDiscoveryStarted();
45 | started = true;
46 | }
47 |
48 | server.receive(packet);
49 | String response = new String(packet.getData(), 0, packet.getLength());
50 | parser.setHostName(packet.getAddress().getHostName());
51 | callback.onDevicesFound(parser.parse(new OnvifResponse(response)));
52 | }
53 |
54 | } catch (IOException ignored) {
55 | } finally {
56 | server.close();
57 | callback.onDiscoveryFinished();
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/OnvifDiscovery.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif;
2 |
3 | import be.teletask.onvif.listeners.DiscoveryCallback;
4 | import be.teletask.onvif.listeners.DiscoveryListener;
5 | import be.teletask.onvif.models.Device;
6 | import be.teletask.onvif.models.DiscoveryPacket;
7 | import be.teletask.onvif.models.OnvifPacket;
8 |
9 |
10 | import java.io.IOException;
11 | import java.net.*;
12 | import java.security.SecureRandom;
13 | import java.util.*;
14 | import java.util.concurrent.*;
15 |
16 | /**
17 | * The OnvifDiscovery class uses the Web Services Dynamic Discovery (WS-Discovery).
18 | * This is a technical specification that defines a multicast discovery protocol
19 | * to locate services on a local network.
20 | *
21 | * It operates over TCP and UDP port 3702 and uses IP multicast address 239.255.255.250.
22 | * As the name suggests, the actual communication between nodes is done using web services standards, notably SOAP-over-UDP.
23 | *
24 | * With WS-Discovery, the discovery tool puts SSDP queries on the network from its unicast address
25 | * to 239.255.255.250 multicast address, sending them to the well-known UDP port 3702.
26 | * The device receives the query, and answers to the discovery tool's unicast IP address from its unicast IP address.
27 | * The reply contains information about the Web Services (WS) available on the device, let alone the device's IP address itself.
28 | *
29 | * UPnP works in a very similar way, but on a different UDP port (1900).
30 | * Compared to the WS-Discovery, the UPnP is intended for a general use (data sharing, communication, entertainment).
31 | *
32 | * Created by Tomas Verhelst on 04/09/2018.
33 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
34 | */
35 | public class OnvifDiscovery {
36 |
37 | //Constants
38 | public static final String TAG = OnvifDiscovery.class.getSimpleName();
39 | private static final String MULTICAST_ADDRESS_IPV4 = "239.255.255.250"; // Simple Service Discovery Protocol
40 | private static final String MULTICAST_ADDRESS_IPV6 = "[FF02::C]";
41 | private static int DISCOVERY_TIMEOUT = 10000;
42 |
43 | private static final Random random = new SecureRandom();
44 |
45 | //Attributes
46 | private int discoveryTimeout = DISCOVERY_TIMEOUT;
47 | private DiscoveryMode mode;
48 | private DiscoveryListener discoveryListener;
49 |
50 | //Constructors
51 | OnvifDiscovery() {
52 | this(DiscoveryMode.ONVIF);
53 | }
54 |
55 | public OnvifDiscovery(DiscoveryMode mode) {
56 | this.mode = mode;
57 | }
58 |
59 | //Methods
60 |
61 | int getDiscoveryTimeout() {
62 | return discoveryTimeout;
63 | }
64 |
65 | /**
66 | * Sets the timeout in milliseconds to discover devices.
67 | * Defaults to 10 seconds
68 | *
69 | * @param timeoutMs the timeout in milliseconds
70 | */
71 | void setDiscoveryTimeout(int timeoutMs) {
72 | discoveryTimeout = timeoutMs;
73 | }
74 |
75 | DiscoveryMode getDiscoveryMode() {
76 | return mode;
77 | }
78 |
79 | void setDiscoveryMode(DiscoveryMode mode) {
80 | this.mode = mode;
81 | }
82 |
83 | public void setDiscoveryListener(DiscoveryListener discoveryListener) {
84 | this.discoveryListener = discoveryListener;
85 | }
86 |
87 | /**
88 | * Broadcasts a SOAP-over-UDP package to all network interfaces
89 | * Discoveries are sent over multicast, replies are sent over unicast (both in UDP)
90 | * It means that the device will receive the discovery query, but it will not be able to answer back to the discovery tool if the peers are working on different subnets.
91 | */
92 | void probe(DiscoveryMode mode, DiscoveryListener discoveryListener) {
93 | //Sets the mode and discovery callback
94 | this.mode = mode;
95 | this.discoveryListener = discoveryListener;
96 |
97 | //Get all interface addresses to send the UDP package on.
98 | List addresses = getInterfaceAddresses();
99 |
100 | //Broadcast the message over all the network interfaces
101 | broadcast(addresses);
102 | }
103 |
104 | //Properties
105 |
106 | private void broadcast(List addresses) {
107 | //Our list will be accessed by multiple threads, hence ConcurrentSkipListSet
108 | Collection devices = new ConcurrentSkipListSet<>();
109 |
110 | //Create a new cached thread pool and a monitor service
111 | ExecutorService executorService = Executors.newCachedThreadPool();
112 | ExecutorService monitor = Executors.newSingleThreadExecutor();
113 | CountDownLatch latch = new CountDownLatch(addresses.size());
114 | List runnables = new ArrayList<>();
115 |
116 | //Add runnables to the list to be executed in order
117 | for (InetAddress address : addresses) {
118 | runnables.add(() -> {
119 | try {
120 | OnvifPacket packet = createDiscoveryPacket();
121 | byte[] data = packet.getData();
122 |
123 | int port = random.nextInt(20000) + 40000;
124 |
125 | DatagramSocket client = new DatagramSocket(port, address);
126 | client.setBroadcast(true);
127 |
128 | //Start a new thread to listen for incoming UDP packages
129 | new DiscoveryThread(client, discoveryTimeout, mode, new DiscoveryCallback() {
130 |
131 | @Override
132 | public void onDiscoveryStarted() {
133 | try {
134 | if (address instanceof Inet4Address) {
135 | client.send(new DatagramPacket(data, data.length, InetAddress.getByName(MULTICAST_ADDRESS_IPV4), mode.port));
136 | } else {
137 | client.send(new DatagramPacket(data, data.length, InetAddress.getByName(MULTICAST_ADDRESS_IPV6), mode.port));
138 | }
139 | } catch (IOException ignored) {
140 | }
141 | }
142 |
143 | @Override
144 | public void onDevicesFound(List onvifDevices) {
145 | devices.addAll(onvifDevices);
146 | }
147 |
148 | @Override
149 | public void onDiscoveryFinished() {
150 | latch.countDown();
151 | }
152 |
153 | }).start();
154 |
155 | } catch (IOException e) {
156 | e.printStackTrace();
157 | }
158 |
159 | });
160 | }
161 |
162 | //Notify that we started our discovery
163 | notifyDiscoveryStarted();
164 |
165 | //Execute a new thread for every probe that should be sent.
166 | monitor.submit(() -> {
167 | for (Runnable runnable : runnables) {
168 | executorService.submit(runnable);
169 | }
170 |
171 | //Stop accepting new tasks and shuts down threads as they finish
172 | try {
173 | executorService.shutdown();
174 |
175 | latch.await(discoveryTimeout, TimeUnit.MILLISECONDS);
176 | boolean cleanShutdown = executorService.awaitTermination(discoveryTimeout,
177 | TimeUnit.MILLISECONDS);
178 |
179 | if (!cleanShutdown) {
180 | executorService.shutdownNow();
181 | }
182 |
183 | notifyDevicesFound(new ArrayList<>(devices));
184 | } catch (InterruptedException e) {
185 | e.printStackTrace();
186 | }
187 |
188 | });
189 | monitor.shutdown();
190 |
191 | }
192 |
193 | private OnvifPacket createDiscoveryPacket() {
194 | String uuid = UUID.randomUUID().toString();
195 | return new DiscoveryPacket(uuid, mode);
196 | }
197 |
198 | List getInterfaceAddresses() {
199 | List addresses = new ArrayList<>();
200 | try {
201 | Enumeration interfaces = NetworkInterface.getNetworkInterfaces();
202 |
203 | while (interfaces.hasMoreElements()) {
204 | NetworkInterface networkInterface = (NetworkInterface) interfaces.nextElement();
205 |
206 | if (networkInterface.isLoopback() || !networkInterface.isUp()) {
207 | continue; // Don't want to broadcast to the loopback interface
208 | }
209 |
210 | for (InterfaceAddress address : networkInterface.getInterfaceAddresses()) {
211 | addresses.add(address.getAddress());
212 | }
213 | }
214 | } catch (SocketException e) {
215 | e.printStackTrace();
216 | }
217 |
218 | return addresses;
219 | }
220 |
221 | List getBroadcastAddresses() {
222 | List addresses = new ArrayList<>();
223 | try {
224 | Enumeration interfaces = NetworkInterface.getNetworkInterfaces();
225 |
226 | while (interfaces.hasMoreElements()) {
227 | NetworkInterface networkInterface = (NetworkInterface) interfaces.nextElement();
228 |
229 | if (networkInterface.isLoopback() || !networkInterface.isUp()) {
230 | continue; // Don't want to broadcast to the loopback interface
231 | }
232 |
233 | for (InterfaceAddress address : networkInterface.getInterfaceAddresses()) {
234 | InetAddress broadcast = address.getBroadcast();
235 | if (broadcast == null) {
236 | continue;
237 | }
238 |
239 | addresses.add(broadcast);
240 | }
241 | }
242 | } catch (SocketException e) {
243 | e.printStackTrace();
244 | }
245 |
246 | return addresses;
247 | }
248 |
249 | String getLocalIpAddress() {
250 |
251 | try {
252 | for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
253 | NetworkInterface intf = en.nextElement();
254 | for (Enumeration enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
255 | InetAddress inetAddress = enumIpAddr.nextElement();
256 | if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
257 | return inetAddress.getHostAddress();
258 | }
259 | }
260 | }
261 | } catch (SocketException ignored) {
262 |
263 | }
264 | return null;
265 | }
266 |
267 | private void notifyDiscoveryStarted() {
268 | if (discoveryListener != null)
269 | discoveryListener.onDiscoveryStarted();
270 | }
271 |
272 | private void notifyDevicesFound(List devices) {
273 | if (discoveryListener != null)
274 | discoveryListener.onDevicesFound(devices);
275 | }
276 |
277 | }
278 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/OnvifExecutor.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif;
2 |
3 | import be.teletask.onvif.listeners.OnvifResponseListener;
4 | import be.teletask.onvif.models.OnvifDevice;
5 | import be.teletask.onvif.models.OnvifServices;
6 | import be.teletask.onvif.parsers.GetDeviceInformationParser;
7 | import be.teletask.onvif.parsers.GetMediaProfilesParser;
8 | import be.teletask.onvif.parsers.GetMediaStreamParser;
9 | import be.teletask.onvif.parsers.GetServicesParser;
10 | import be.teletask.onvif.requests.*;
11 | import be.teletask.onvif.responses.OnvifResponse;
12 | import com.burgstaller.okhttp.AuthenticationCacheInterceptor;
13 | import com.burgstaller.okhttp.CachingAuthenticatorDecorator;
14 | import com.burgstaller.okhttp.digest.CachingAuthenticator;
15 | import com.burgstaller.okhttp.digest.Credentials;
16 | import com.burgstaller.okhttp.digest.DigestAuthenticator;
17 | import okhttp3.*;
18 | import okio.Buffer;
19 |
20 |
21 | import java.io.IOException;
22 | import java.util.Map;
23 | import java.util.concurrent.ConcurrentHashMap;
24 | import java.util.concurrent.TimeUnit;
25 |
26 | /**
27 | * Created by Tomas Verhelst on 03/09/2018.
28 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
29 | */
30 | public class OnvifExecutor {
31 |
32 | //Constants
33 | public static final String TAG = OnvifExecutor.class.getSimpleName();
34 |
35 | //Attributes
36 | private OkHttpClient client;
37 | private MediaType reqBodyType;
38 | private RequestBody reqBody;
39 |
40 | private Credentials credentials;
41 | private OnvifResponseListener onvifResponseListener;
42 |
43 | //Constructors
44 |
45 | OnvifExecutor(OnvifResponseListener onvifResponseListener) {
46 | this.onvifResponseListener = onvifResponseListener;
47 | credentials = new Credentials("username", "password");
48 | DigestAuthenticator authenticator = new DigestAuthenticator(credentials);
49 | Map authCache = new ConcurrentHashMap<>();
50 |
51 | client = new OkHttpClient.Builder()
52 | .connectTimeout(10000, TimeUnit.SECONDS)
53 | .writeTimeout(100, TimeUnit.SECONDS)
54 | .readTimeout(10000, TimeUnit.SECONDS)
55 | .authenticator(new CachingAuthenticatorDecorator(authenticator, authCache))
56 | .addInterceptor(new AuthenticationCacheInterceptor(authCache))
57 | .build();
58 |
59 | reqBodyType = MediaType.parse("application/soap+xml; charset=utf-8;");
60 | }
61 |
62 | //Methods
63 |
64 | /**
65 | * Sends a request to the Onvif-compatible device.
66 | *
67 | * @param device
68 | * @param request
69 | */
70 | void sendRequest(OnvifDevice device, OnvifRequest request) {
71 | credentials.setUserName(device.getUsername());
72 | credentials.setPassword(device.getPassword());
73 | reqBody = RequestBody.create(reqBodyType, OnvifXMLBuilder.getSoapHeader() + request.getXml() + OnvifXMLBuilder.getEnvelopeEnd());
74 | performXmlRequest(device, request, buildOnvifRequest(device, request));
75 | }
76 |
77 | /**
78 | * Clears up the resources.
79 | */
80 | void clear() {
81 | onvifResponseListener = null;
82 | }
83 |
84 | //Properties
85 |
86 | public void setOnvifResponseListener(OnvifResponseListener onvifResponseListener) {
87 | this.onvifResponseListener = onvifResponseListener;
88 | }
89 |
90 | private void performXmlRequest(OnvifDevice device, OnvifRequest request, Request xmlRequest) {
91 | if (xmlRequest == null)
92 | return;
93 |
94 | client.newCall(xmlRequest)
95 | .enqueue(new Callback() {
96 |
97 | @Override
98 | public void onResponse(Call call, Response xmlResponse) throws IOException {
99 |
100 | OnvifResponse response = new OnvifResponse(request);
101 | ResponseBody xmlBody = xmlResponse.body();
102 |
103 | if (xmlResponse.code() == 200 && xmlBody != null) {
104 | response.setSuccess(true);
105 | response.setXml(xmlBody.string());
106 | parseResponse(device, response);
107 | return;
108 | }
109 |
110 | String errorMessage = "";
111 | if (xmlBody != null)
112 | errorMessage = xmlBody.string();
113 |
114 | onvifResponseListener.onError(device, xmlResponse.code(), errorMessage);
115 | }
116 |
117 | @Override
118 | public void onFailure(Call call, IOException e) {
119 | onvifResponseListener.onError(device, -1, e.getMessage());
120 | }
121 |
122 | });
123 | }
124 |
125 | private void parseResponse(OnvifDevice device, OnvifResponse response) {
126 | switch (response.request().getType()) {
127 | case GET_SERVICES:
128 | OnvifServices path = new GetServicesParser().parse(response);
129 | device.setPath(path);
130 | ((GetServicesRequest) response.request()).getListener().onServicesReceived(device, path);
131 | break;
132 | case GET_DEVICE_INFORMATION:
133 | ((GetDeviceInformationRequest) response.request()).getListener().onDeviceInformationReceived(device,
134 | new GetDeviceInformationParser().parse(response));
135 | break;
136 | case GET_MEDIA_PROFILES:
137 | ((GetMediaProfilesRequest) response.request()).getListener().onMediaProfilesReceived(device,
138 | new GetMediaProfilesParser().parse(response));
139 | break;
140 | case GET_STREAM_URI:
141 | GetMediaStreamRequest streamRequest = (GetMediaStreamRequest) response.request();
142 | streamRequest.getListener().onMediaStreamURIReceived(device, streamRequest.getMediaProfile(),
143 | new GetMediaStreamParser().parse(response));
144 | break;
145 | default:
146 | onvifResponseListener.onResponse(device, response);
147 | break;
148 | }
149 | }
150 |
151 | private Request buildOnvifRequest(OnvifDevice device, OnvifRequest request) {
152 | return new Request.Builder()
153 | .url(getUrlForRequest(device, request))
154 | .addHeader("Content-Type", "text/xml; charset=utf-8")
155 | .post(reqBody)
156 | .build();
157 | }
158 |
159 | private String getUrlForRequest(OnvifDevice device, OnvifRequest request) {
160 | return device.getHostName() + getPathForRequest(device, request);
161 | }
162 |
163 | private String getPathForRequest(OnvifDevice device, OnvifRequest request) {
164 | switch (request.getType()) {
165 | case GET_SERVICES:
166 | return device.getPath().getServicesPath();
167 | case GET_DEVICE_INFORMATION:
168 | return device.getPath().getDeviceInformationPath();
169 | case GET_MEDIA_PROFILES:
170 | return device.getPath().getProfilesPath();
171 | case GET_STREAM_URI:
172 | return device.getPath().getStreamURIPath();
173 | }
174 |
175 | return device.getPath().getServicesPath();
176 | }
177 |
178 | private String bodyToString(Request request) {
179 |
180 | try {
181 | Request copy = request.newBuilder().build();
182 | Buffer buffer = new Buffer();
183 | if (copy.body() != null)
184 | copy.body().writeTo(buffer);
185 | return buffer.readUtf8();
186 | } catch (IOException e) {
187 | e.printStackTrace();
188 | return "";
189 | }
190 | }
191 |
192 | }
193 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/OnvifManager.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif;
2 |
3 | import be.teletask.onvif.listeners.*;
4 | import be.teletask.onvif.models.OnvifDevice;
5 | import be.teletask.onvif.models.OnvifMediaProfile;
6 | import be.teletask.onvif.requests.*;
7 | import be.teletask.onvif.responses.OnvifResponse;
8 |
9 |
10 | /**
11 | * Created by Tomas Verhelst on 03/09/2018.
12 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
13 | */
14 | public class OnvifManager implements OnvifResponseListener {
15 |
16 | //Constants
17 | public final static String TAG = OnvifManager.class.getSimpleName();
18 |
19 | //Attributes
20 | private OnvifExecutor executor;
21 | private OnvifResponseListener onvifResponseListener;
22 |
23 | //Constructors
24 | public OnvifManager() {
25 | this(null);
26 | }
27 |
28 | private OnvifManager(OnvifResponseListener onvifResponseListener) {
29 | this.onvifResponseListener = onvifResponseListener;
30 | executor = new OnvifExecutor(this);
31 | }
32 |
33 | //Methods
34 | public void getServices(OnvifDevice device, OnvifServicesListener listener) {
35 | OnvifRequest request = new GetServicesRequest(listener);
36 | executor.sendRequest(device, request);
37 | }
38 |
39 | public void getDeviceInformation(OnvifDevice device, OnvifDeviceInformationListener listener) {
40 | OnvifRequest request = new GetDeviceInformationRequest(listener);
41 | executor.sendRequest(device, request);
42 | }
43 |
44 | public void getMediaProfiles(OnvifDevice device, OnvifMediaProfilesListener listener) {
45 | OnvifRequest request = new GetMediaProfilesRequest(listener);
46 | executor.sendRequest(device, request);
47 | }
48 |
49 | public void getMediaStreamURI(OnvifDevice device, OnvifMediaProfile profile, OnvifMediaStreamURIListener listener) {
50 | OnvifRequest request = new GetMediaStreamRequest(profile, listener);
51 | executor.sendRequest(device, request);
52 | }
53 |
54 | public void sendOnvifRequest(OnvifDevice device, OnvifRequest request) {
55 | executor.sendRequest(device, request);
56 | }
57 |
58 | public void setOnvifResponseListener(OnvifResponseListener onvifResponseListener) {
59 | this.onvifResponseListener = onvifResponseListener;
60 | }
61 |
62 | /**
63 | * Clear up the resources.
64 | */
65 | public void destroy() {
66 | onvifResponseListener = null;
67 | executor.clear();
68 | }
69 |
70 | @Override
71 | public void onResponse(OnvifDevice onvifDevice, OnvifResponse response) {
72 | if (onvifResponseListener != null)
73 | onvifResponseListener.onResponse(onvifDevice, response);
74 | }
75 |
76 | @Override
77 | public void onError(OnvifDevice onvifDevice, int errorCode, String errorMessage) {
78 | if (onvifResponseListener != null)
79 | onvifResponseListener.onError(onvifDevice, errorCode, errorMessage);
80 | }
81 |
82 | }
83 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/OnvifUtils.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif;
2 |
3 | import org.xmlpull.v1.XmlPullParser;
4 | import org.xmlpull.v1.XmlPullParserException;
5 |
6 | import java.io.IOException;
7 | import java.net.MalformedURLException;
8 | import java.net.URL;
9 |
10 | /**
11 | * Created by Tomas Verhelst on 03/09/2018.
12 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
13 | */
14 | public class OnvifUtils {
15 |
16 | /**
17 | * Util method to retrieve a path from an URL (without IP address and port)
18 | *
19 | * @param uri example input: `http://192.168.1.0:8791/cam/realmonitor?audio=1`
20 | * @example:
21 | * @result example output: `cam/realmonitor?audio=1`
22 | */
23 | public static String getPathFromURL(String uri) {
24 | URL url;
25 | try {
26 | url = new URL(uri);
27 | } catch (MalformedURLException e) {
28 | return "";
29 | }
30 |
31 | String result = url.getPath();
32 |
33 | if (url.getQuery() != null) {
34 | result += url.getQuery();
35 | }
36 |
37 | return result;
38 | }
39 |
40 | /**
41 | * Util method for parsing. Retrieve the XAddr from the XmlPullParser given.
42 | */
43 | public static String retrieveXAddr(XmlPullParser xpp) throws IOException, XmlPullParserException {
44 | String result = "";
45 | int eventType = xpp.getEventType();
46 | while (eventType != XmlPullParser.END_DOCUMENT || (eventType == XmlPullParser.END_TAG && xpp.getName().equals("Service"))) {
47 |
48 | if (eventType == XmlPullParser.START_TAG && xpp.getName().equals("XAddr")) {
49 | xpp.next();
50 | result = xpp.getText();
51 | break;
52 | }
53 | eventType = xpp.next();
54 | }
55 |
56 | return result;
57 | }
58 |
59 | /**
60 | * Util method for parsing.
61 | * Retrieve the XAddrs from the XmlPullParser given.
62 | */
63 | public static String retrieveXAddrs(XmlPullParser xpp) throws IOException, XmlPullParserException {
64 | String result = "";
65 | int eventType = xpp.getEventType();
66 | while (eventType != XmlPullParser.END_DOCUMENT) {
67 |
68 | if (eventType == XmlPullParser.START_TAG && xpp.getName().equals("XAddrs")) {
69 | xpp.next();
70 | result = xpp.getText();
71 | break;
72 | }
73 | eventType = xpp.next();
74 | }
75 |
76 | return result;
77 | }
78 |
79 | }
80 |
81 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/OnvifXMLBuilder.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif;
2 |
3 | /**
4 | * Created by Tomas Verhelst on 03/09/2018.
5 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
6 | */
7 | public class OnvifXMLBuilder {
8 |
9 | //Constants
10 | public static final String TAG = OnvifXMLBuilder.class.getSimpleName();
11 |
12 | //Attributes
13 |
14 | public static String getSoapHeader() {
15 | return "" +
16 | "" +
20 | "";
21 | }
22 |
23 | public static String getEnvelopeEnd() {
24 | return "";
25 | }
26 |
27 | public static String getDiscoverySoapHeader() {
28 | return "" +
29 | "" +
35 | "" +
36 | "http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe" +
37 | "urn:uuid:%s\n" +
38 | "urn:schemas-xmlsoap-org:ws:2005:04:discovery\n" +
39 | "" +
40 | "";
41 | }
42 |
43 | public static String getDiscoverySoapBody() {
44 | return "";
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/listeners/DiscoveryCallback.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.listeners;
2 |
3 | import java.util.List;
4 |
5 | import be.teletask.onvif.models.Device;
6 |
7 | /**
8 | * Created by Tomas Verhelst on 04/09/2018.
9 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
10 | */
11 | public interface DiscoveryCallback {
12 |
13 | void onDiscoveryStarted();
14 |
15 | void onDevicesFound(List devices);
16 |
17 | void onDiscoveryFinished();
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/listeners/DiscoveryListener.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.listeners;
2 |
3 | import java.util.List;
4 |
5 | import be.teletask.onvif.models.Device;
6 |
7 | /**
8 | * Created by Tomas Verhelst on 04/09/2018.
9 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
10 | */
11 | public interface DiscoveryListener {
12 |
13 | void onDiscoveryStarted();
14 |
15 | void onDevicesFound(List devices);
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/listeners/OnvifDeviceInformationListener.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.listeners;
2 |
3 | import be.teletask.onvif.models.OnvifDevice;
4 | import be.teletask.onvif.models.OnvifDeviceInformation;
5 |
6 |
7 | /**
8 | * Created by Tomas Verhelst on 03/09/2018.
9 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
10 | */
11 | public interface OnvifDeviceInformationListener {
12 |
13 | void onDeviceInformationReceived(OnvifDevice device, OnvifDeviceInformation deviceInformation);
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/listeners/OnvifMediaProfilesListener.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.listeners;
2 |
3 | import be.teletask.onvif.models.OnvifDevice;
4 | import be.teletask.onvif.models.OnvifMediaProfile;
5 |
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * Created by Tomas Verhelst on 03/09/2018.
11 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
12 | */
13 | public interface OnvifMediaProfilesListener {
14 |
15 | void onMediaProfilesReceived(OnvifDevice device, List mediaProfiles);
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/listeners/OnvifMediaStreamURIListener.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.listeners;
2 |
3 | import be.teletask.onvif.models.OnvifDevice;
4 | import be.teletask.onvif.models.OnvifMediaProfile;
5 |
6 |
7 | /**
8 | * Created by Tomas Verhelst on 03/09/2018.
9 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
10 | */
11 | public interface OnvifMediaStreamURIListener {
12 |
13 | void onMediaStreamURIReceived(OnvifDevice device, OnvifMediaProfile profile, String uri);
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/listeners/OnvifResponseListener.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.listeners;
2 |
3 | import be.teletask.onvif.models.OnvifDevice;
4 | import be.teletask.onvif.responses.OnvifResponse;
5 |
6 |
7 | /**
8 | * Created by Tomas Verhelst on 03/09/2018.
9 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
10 | */
11 | public interface OnvifResponseListener {
12 |
13 | void onResponse(OnvifDevice onvifDevice, OnvifResponse response);
14 |
15 | void onError(OnvifDevice onvifDevice, int errorCode, String errorMessage);
16 | }
17 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/listeners/OnvifServicesListener.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.listeners;
2 |
3 | import be.teletask.onvif.models.OnvifDevice;
4 | import be.teletask.onvif.models.OnvifServices;
5 |
6 |
7 | /**
8 | * Created by Tomas Verhelst on 03/09/2018.
9 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
10 | */
11 | public interface OnvifServicesListener {
12 |
13 | void onServicesReceived(OnvifDevice onvifDevice, OnvifServices paths);
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/models/Device.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.models;
2 |
3 |
4 |
5 | import java.util.Locale;
6 |
7 | /**
8 | * Created by Tomas Verhelst on 06/09/2018.
9 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
10 | */
11 | public abstract class Device implements Comparable {
12 |
13 | //Constants
14 | public static final String TAG = Device.class.getSimpleName();
15 | private static final String FORMAT_HTTP = "http://%s";
16 |
17 | //Attributes
18 | private String host;
19 | private String username;
20 | private String password;
21 | private boolean connected;
22 |
23 | //Constructors
24 | public Device(String host) {
25 | this(host, "", "");
26 | }
27 |
28 | public Device(String host, String username, String password) {
29 | this.host = buildUrl(host);
30 | this.username = username;
31 | this.password = password;
32 | }
33 |
34 | //Properties
35 |
36 | public String getHostName() {
37 | return host;
38 | }
39 |
40 | public void setHostName(String url) {
41 | host = url;
42 | }
43 |
44 | public String getUsername() {
45 | return username;
46 | }
47 |
48 | public void setUsername(String username) {
49 | this.username = username;
50 | }
51 |
52 | public String getPassword() {
53 | return password;
54 | }
55 |
56 | public void setPassword(String password) {
57 | this.password = password;
58 | }
59 |
60 | public void setConnected(boolean connected) {
61 | this.connected = connected;
62 | }
63 |
64 | @Override
65 | public int compareTo(Device device) {
66 | return getHostName().compareTo(device.getHostName());
67 | }
68 |
69 | private String buildUrl(String url) {
70 | if (url.startsWith("http://") || url.startsWith("https://"))
71 | return url;
72 |
73 | return String.format(Locale.getDefault(), FORMAT_HTTP, url);
74 | }
75 |
76 | public abstract DeviceType getType();
77 | }
78 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/models/DeviceType.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.models;
2 |
3 | /**
4 | * Created by Tomas Verhelst on 06/09/2018.
5 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
6 | */
7 | public enum DeviceType {
8 | ONVIF,
9 | UPNP
10 | }
11 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/models/DiscoveryPacket.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.models;
2 |
3 | import be.teletask.onvif.DiscoveryMode;
4 | import be.teletask.onvif.OnvifXMLBuilder;
5 |
6 |
7 | import java.util.Locale;
8 |
9 | /**
10 | * Created by Tomas Verhelst on 05/09/2018.
11 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
12 | */
13 | public class DiscoveryPacket extends OnvifPacket {
14 |
15 | //Constants
16 | public static final String TAG = DiscoveryPacket.class.getSimpleName();
17 | private static final String LINE_END = "\r\n";
18 | private static final String DEFAULT_QUERY = "M-SEARCH * HTTP/1.1" + LINE_END +
19 | "HOST: 239.255.255.250:1900" + LINE_END +
20 | "MAN: \"ssdp:discover\"" + LINE_END +
21 | "MX: 1" + LINE_END +
22 | //"ST: urn:schemas-upnp-org:service:AVTransport:1" + LINE_END + // Use for Sonos
23 | //"ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1" + LINE_END + // Use for Routes
24 | "ST: ssdp:all" + LINE_END + // Use this for all UPnP Devices
25 | LINE_END;
26 |
27 | //Attributes
28 | private final String uuid;
29 | private final DiscoveryMode mode;
30 |
31 | //Constructors
32 | public DiscoveryPacket(String uuid) {
33 | this(uuid, DiscoveryMode.ONVIF);
34 | }
35 |
36 | public DiscoveryPacket(String uuid, DiscoveryMode mode) {
37 | this.uuid = uuid;
38 | this.mode = mode;
39 | }
40 |
41 | //Properties
42 | @Override
43 | public byte[] getData() {
44 | String data = "";
45 | if (mode.equals(DiscoveryMode.ONVIF)) {
46 | StringBuilder builder = new StringBuilder();
47 | String header = String.format(Locale.getDefault(), OnvifXMLBuilder.getDiscoverySoapHeader(), uuid);
48 | builder.append(header);
49 | builder.append(OnvifXMLBuilder.getDiscoverySoapBody());
50 | builder.append(OnvifXMLBuilder.getEnvelopeEnd());
51 | data = builder.toString();
52 | } else if (mode.equals(DiscoveryMode.UPNP)) {
53 | data = DEFAULT_QUERY;
54 | }
55 |
56 | return data.getBytes();
57 | }
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/models/DiscoveryType.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.models;
2 |
3 | /**
4 | * Created by Tomas Verhelst on 04/09/2018.
5 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
6 | */
7 | public enum DiscoveryType {
8 | DEVICE(0, "Device"),
9 | NETWORK_VIDEO_TRANSMITTER(1, "NetworkVideoTransmitter");
10 |
11 | public final int id;
12 | public final String type;
13 |
14 | DiscoveryType(int id, String type) {
15 | this.id = id;
16 | this.type = type;
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/models/OnvifDevice.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.models;
2 |
3 |
4 |
5 | import java.util.ArrayList;
6 | import java.util.List;
7 |
8 | /**
9 | * Created by Tomas Verhelst on 03/09/2018.
10 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
11 | */
12 | public class OnvifDevice extends Device {
13 |
14 | //Constants
15 | public static final String TAG = OnvifDevice.class.getSimpleName();
16 |
17 | //Attributes
18 | private OnvifServices path;
19 | private List addresses;
20 |
21 | //Constructors
22 | public OnvifDevice(String hostName) {
23 | this(hostName, "", "");
24 | }
25 |
26 | public OnvifDevice(String hostName, String username, String password) {
27 | super(hostName, username, password);
28 | path = new OnvifServices();
29 | addresses = new ArrayList<>();
30 | }
31 |
32 | //Methods
33 | public void addAddress(String address) {
34 | addresses.add(address);
35 | }
36 |
37 | //Properties
38 | public OnvifServices getPath() {
39 | return path;
40 | }
41 |
42 | public void setPath(OnvifServices path) {
43 | this.path = path;
44 | }
45 |
46 | public List getAddresses() {
47 | return addresses;
48 | }
49 |
50 | public void setAddresses(List addresses) {
51 | this.addresses = addresses;
52 | }
53 |
54 | @Override
55 | public DeviceType getType() {
56 | return DeviceType.ONVIF;
57 | }
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/models/OnvifDeviceInformation.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.models;
2 |
3 | /**
4 | * Created by Tomas Verhelst on 03/09/2018.
5 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
6 | */
7 | public class OnvifDeviceInformation {
8 |
9 | //Constants
10 | public static final String TAG = OnvifDeviceInformation.class.getSimpleName();
11 |
12 | //Attributes
13 |
14 | //Constructors
15 | private String manufacturer;
16 | private String model;
17 | private String firmwareVersion;
18 | private String serialNumber;
19 | private String hardwareId;
20 |
21 | //Constructors
22 | public OnvifDeviceInformation() {
23 | }
24 |
25 | //Properties
26 |
27 | public String getManufacturer() {
28 | return manufacturer;
29 | }
30 |
31 | public void setManufacturer(String manufacturer) {
32 | this.manufacturer = manufacturer;
33 | }
34 |
35 | public String getModel() {
36 | return model;
37 | }
38 |
39 | public void setModel(String model) {
40 | this.model = model;
41 | }
42 |
43 | public String getFirmwareVersion() {
44 | return firmwareVersion;
45 | }
46 |
47 | public void setFirmwareVersion(String firmwareVersion) {
48 | this.firmwareVersion = firmwareVersion;
49 | }
50 |
51 | public String getSerialNumber() {
52 | return serialNumber;
53 | }
54 |
55 | public void setSerialNumber(String serialNumber) {
56 | this.serialNumber = serialNumber;
57 | }
58 |
59 | public String getHardwareId() {
60 | return hardwareId;
61 | }
62 |
63 | public void setHardwareId(String hardwareId) {
64 | this.hardwareId = hardwareId;
65 | }
66 |
67 | @Override
68 | public String toString() {
69 | return "OnvifDeviceInformation{" +
70 | "manufacturer='" + manufacturer + '\'' +
71 | ", model='" + model + '\'' +
72 | ", firmwareVersion='" + firmwareVersion + '\'' +
73 | ", serialNumber='" + serialNumber + '\'' +
74 | ", hardwareId='" + hardwareId + '\'' +
75 | '}';
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/models/OnvifMediaProfile.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.models;
2 |
3 | /**
4 | * Created by Tomas Verhelst on 03/09/2018.
5 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
6 | */
7 | public class OnvifMediaProfile {
8 |
9 | //Constants
10 | public static final String TAG = OnvifMediaProfile.class.getSimpleName();
11 |
12 | //Attributes
13 | private final String name;
14 | private final String token;
15 |
16 | //Constructors
17 |
18 | public OnvifMediaProfile(String name, String token) {
19 | this.name = name;
20 | this.token = token;
21 | }
22 |
23 | //Properties
24 |
25 | public String getName() {
26 | return name;
27 | }
28 |
29 | public String getToken() {
30 | return token;
31 | }
32 |
33 | @Override
34 | public String toString() {
35 | return "OnvifMediaProfile{" +
36 | "name='" + name + '\'' +
37 | ", token='" + token + '\'' +
38 | '}';
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/models/OnvifPacket.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.models;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * Created by Tomas Verhelst on 05/09/2018.
8 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
9 | */
10 | public class OnvifPacket {
11 |
12 | //Constants
13 | public static final String TAG = OnvifPacket.class.getSimpleName();
14 |
15 | //Attributes
16 | private String name;
17 | private String timestamp;
18 | private byte[] data;
19 |
20 | //Constructors
21 | public OnvifPacket() {
22 | this("", new byte[0]);
23 | }
24 |
25 | public OnvifPacket(String name) {
26 | this(name, new byte[0]);
27 | }
28 |
29 | public OnvifPacket(String name, byte[] data) {
30 | this.name = name;
31 | this.data = data;
32 | }
33 |
34 | //Methods
35 |
36 | //Properties
37 |
38 | public String getName() {
39 | return name;
40 | }
41 |
42 | public void setName(String name) {
43 | this.name = name;
44 | }
45 |
46 | public byte[] getData() {
47 | return data;
48 | }
49 |
50 | public void setData(byte[] data) {
51 | this.data = data;
52 | }
53 |
54 | public static byte[] asciiToBytes(String ascii) {
55 |
56 | int val1, val2, val3;
57 | char c1, c2;
58 |
59 | List bytes = new ArrayList<>();
60 |
61 | ascii = ascii.replace("\\r", "\\0d");
62 | ascii = ascii.replace("\\n", "\\0a");
63 |
64 | for (int i = 0; i < ascii.length(); i++) {
65 | val1 = iAt(ascii, i);
66 | if (val1 >= 0x20 && val1 <= 0x7E) {
67 |
68 | if (val1 == (((int) '\\') & 0xff)) {
69 | val2 = iAt(ascii, i + 1);
70 | val3 = iAt(ascii, i + 2);
71 | if (val2 > -1 && val3 > -1) {
72 | c1 = ascii.charAt(i + 1);
73 | c2 = ascii.charAt(i + 2);
74 |
75 | try {
76 | val2 = Integer.parseInt((c1 + "") + (c2 + ""), 16) & 0xff;
77 | val3 = 0;
78 |
79 | bytes.add((byte) (val2 + val3));
80 |
81 | } catch (NumberFormatException e) {
82 | e.printStackTrace();
83 | }
84 |
85 | i += 2;
86 | }
87 |
88 | } else {
89 | val1 = iAt(ascii, i);
90 | bytes.add((byte) (val1));
91 |
92 | }
93 | }
94 | }
95 |
96 | return toByteArray(bytes);
97 | }
98 |
99 | private static int iAt(String s, int index) {
100 | if (index < s.length()) {
101 | return (((int) s.charAt(index)) & 0xff);
102 | } else {
103 | return -1;
104 | }
105 | }
106 |
107 | private static byte[] toByteArray(List list) {
108 | byte[] ret = new byte[list.size()];
109 | for (int i = 0; i < ret.length; i++)
110 | ret[i] = list.get(i);
111 | return ret;
112 | }
113 |
114 | public String toAscii(byte[] data) {
115 | StringBuilder returnString = new StringBuilder();
116 | for (int item : data) {
117 | if (item == 0x0A) {
118 | returnString.append("\\n");
119 |
120 | } else if (item == 0x0D) {
121 | returnString.append("\\r");
122 |
123 | } else if (item >= 0x20 && item <= 0x7E) {
124 | returnString.append((char) item);
125 | } else {
126 | String hex = Integer.toHexString(item & 0xff);
127 | if (hex.length() == 1) {
128 | hex = "0" + hex;
129 | }
130 | returnString.append("\\").append(hex);
131 | }
132 | }
133 |
134 | return returnString.toString();
135 | }
136 |
137 | }
138 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/models/OnvifServices.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.models;
2 |
3 | /**
4 | * Created by Tomas Verhelst on 03/09/2018.
5 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
6 | */
7 | public class OnvifServices {
8 |
9 | //Constants
10 | public static final String TAG = OnvifServices.class.getSimpleName();
11 | public static final String ONVIF_PATH_SERVICES = "/onvif/device_service";
12 | public static final String ONVIF_PATH_DEVICE_INFORMATION = "/onvif/device_service";
13 | public static final String ONVIF_PATH_PROFILES = "/onvif/device_service";
14 | public static final String ONVIF_PATH_STREAM_URI = "/onvif/device_service";
15 |
16 | //Attributes
17 | private String servicesPath = ONVIF_PATH_SERVICES;
18 | private String deviceInformationPath = ONVIF_PATH_DEVICE_INFORMATION;
19 | private String profilesPath = ONVIF_PATH_PROFILES;
20 | private String streamURIPath = ONVIF_PATH_STREAM_URI;
21 |
22 | //Constructors
23 | public OnvifServices() {
24 | }
25 |
26 | //Properties
27 |
28 | public String getServicesPath() {
29 | return servicesPath;
30 | }
31 |
32 | public void setServicesPath(String servicesPath) {
33 | this.servicesPath = servicesPath;
34 | }
35 |
36 | public String getDeviceInformationPath() {
37 | return deviceInformationPath;
38 | }
39 |
40 | public void setDeviceInformationPath(String deviceInformationPath) {
41 | this.deviceInformationPath = deviceInformationPath;
42 | }
43 |
44 | public String getProfilesPath() {
45 | return profilesPath;
46 | }
47 |
48 | public void setProfilesPath(String profilesPath) {
49 | this.profilesPath = profilesPath;
50 | }
51 |
52 | public String getStreamURIPath() {
53 | return streamURIPath;
54 | }
55 |
56 | public void setStreamURIPath(String streamURIPath) {
57 | this.streamURIPath = streamURIPath;
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/models/OnvifType.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.models;
2 |
3 | /**
4 | * Created by Tomas Verhelst on 04/09/2018.
5 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
6 | */
7 | public enum OnvifType {
8 | CUSTOM(""),
9 | GET_SERVICES("http://www.onvif.org/ver10/device/wsdl"),
10 | GET_DEVICE_INFORMATION("http://www.onvif.org/ver10/device/wsdl"),
11 | GET_MEDIA_PROFILES("http://www.onvif.org/ver10/media/wsdl"),
12 | GET_STREAM_URI("http://www.onvif.org/ver10/media/wsdl");
13 |
14 | public final String namespace;
15 |
16 | OnvifType(String namespace) {
17 | this.namespace = namespace;
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/models/UPnPDevice.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.models;
2 |
3 | import be.teletask.onvif.upnp.UPnPDeviceInformation;
4 |
5 |
6 | /**
7 | * Created by Tomas Verhelst on 06/09/2018.
8 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
9 | */
10 | public class UPnPDevice extends Device {
11 |
12 | //Constants
13 | public static final String TAG = UPnPDevice.class.getSimpleName();
14 |
15 | //Attributes
16 | private String header;
17 | private String location;
18 | private String server;
19 | private String usn;
20 | private String st;
21 | private UPnPDeviceInformation deviceInformation;
22 |
23 | //Constructors
24 |
25 | public UPnPDevice(String hostName) {
26 | this(hostName, "", "", "", "", "");
27 | }
28 |
29 | public UPnPDevice(String hostName, String header, String location,
30 | String server, String usn, String st) {
31 | super(hostName);
32 | deviceInformation = new UPnPDeviceInformation();
33 | initHeaders(header, location, server, usn, st);
34 | }
35 |
36 | //Methods
37 | private void initHeaders(String header, String location,
38 | String server, String usn, String st) {
39 | this.header = header;
40 | this.location = location;
41 | this.server = server;
42 | this.usn = usn;
43 | this.st = st;
44 | }
45 |
46 | //Properties
47 |
48 | public String getHeader() {
49 | return header;
50 | }
51 |
52 | public void setHeader(String header) {
53 | this.header = header;
54 | }
55 |
56 | public String getLocation() {
57 | return location;
58 | }
59 |
60 | public void setLocation(String location) {
61 | this.location = location;
62 | }
63 |
64 | public String getServer() {
65 | return server;
66 | }
67 |
68 | public void setServer(String server) {
69 | this.server = server;
70 | }
71 |
72 | public String getUSN() {
73 | return usn;
74 | }
75 |
76 | public void setUSN(String usn) {
77 | this.usn = usn;
78 | }
79 |
80 | public String getST() {
81 | return st;
82 | }
83 |
84 | public void setST(String st) {
85 | this.st = st;
86 | }
87 |
88 | public UPnPDeviceInformation getDeviceInformation() {
89 | return deviceInformation;
90 | }
91 |
92 | public void setDeviceInformation(UPnPDeviceInformation deviceInformation) {
93 | this.deviceInformation = deviceInformation;
94 | }
95 |
96 | @Override
97 | public DeviceType getType() {
98 | return DeviceType.UPNP;
99 | }
100 |
101 | }
102 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/parsers/DiscoveryParser.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.parsers;
2 |
3 | import be.teletask.onvif.DiscoveryMode;
4 | import be.teletask.onvif.OnvifUtils;
5 | import be.teletask.onvif.models.Device;
6 | import be.teletask.onvif.models.DiscoveryType;
7 | import be.teletask.onvif.models.OnvifDevice;
8 | import be.teletask.onvif.models.UPnPDevice;
9 | import be.teletask.onvif.responses.OnvifResponse;
10 |
11 | import org.xmlpull.v1.XmlPullParser;
12 | import org.xmlpull.v1.XmlPullParserException;
13 |
14 | import java.io.IOException;
15 | import java.io.StringReader;
16 | import java.util.ArrayList;
17 | import java.util.List;
18 |
19 | /**
20 | * Created by Tomas Verhelst on 04/09/2018.
21 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
22 | */
23 | public class DiscoveryParser extends OnvifParser> {
24 |
25 | //Constants
26 | public static final String TAG = DiscoveryParser.class.getSimpleName();
27 | private static final String LINE_END = "\r\n";
28 | private static String KEY_UPNP_LOCATION = "LOCATION: ";
29 | private static String KEY_UPNP_SERVER = "SERVER: ";
30 | private static String KEY_UPNP_USN = "USN: ";
31 | private static String KEY_UPNP_ST = "ST: ";
32 |
33 | //Attributes
34 | private DiscoveryMode mode;
35 | private String hostName;
36 |
37 | //Constructors
38 | public DiscoveryParser(DiscoveryMode mode) {
39 | this.mode = mode;
40 | hostName = "";
41 | }
42 |
43 | //Methods
44 |
45 | @Override
46 | public List parse(OnvifResponse response) {
47 | List devices = new ArrayList<>();
48 |
49 | switch (mode) {
50 | case ONVIF:
51 | devices.addAll(parseOnvif(response));
52 | break;
53 | case UPNP:
54 | devices.add(parseUPnP(response));
55 | break;
56 | }
57 |
58 | return devices;
59 | }
60 |
61 | private List parseOnvif(OnvifResponse response) {
62 | ArrayList devices = new ArrayList<>();
63 | try {
64 | getXpp().setInput(new StringReader(response.getXml()));
65 | eventType = getXpp().getEventType();
66 | while (eventType != XmlPullParser.END_DOCUMENT) {
67 |
68 | if (eventType == XmlPullParser.START_TAG && getXpp().getName().equals("Types")) {
69 | getXpp().next();
70 | String type = getXpp().getText();
71 |
72 | if (mode.equals(DiscoveryMode.ONVIF) && type.contains(DiscoveryType.NETWORK_VIDEO_TRANSMITTER.type)) {
73 | String uri = OnvifUtils.retrieveXAddrs(getXpp());
74 | devices.addAll(parseDevicesFromUri(uri));
75 | }
76 | }
77 |
78 | eventType = getXpp().next();
79 | }
80 | } catch (XmlPullParserException | IOException e) {
81 | e.printStackTrace();
82 | }
83 |
84 | return devices;
85 | }
86 |
87 | private Device parseUPnP(OnvifResponse response) {
88 | String header = response.getXml();
89 | String location = parseUPnPHeader(header, KEY_UPNP_LOCATION);
90 | String server = parseUPnPHeader(header, KEY_UPNP_SERVER);
91 | String usn = parseUPnPHeader(header, KEY_UPNP_USN);
92 | String st = parseUPnPHeader(header, KEY_UPNP_ST);
93 | return new UPnPDevice(getHostName(), header, location, server, usn, st);
94 | }
95 |
96 | //Properties
97 |
98 | private String getHostName() {
99 | return hostName;
100 | }
101 |
102 | public void setHostName(String hostName) {
103 | this.hostName = hostName;
104 | }
105 |
106 | private List parseDevicesFromUri(String uri) {
107 | List devices = new ArrayList<>();
108 | String[] uris = uri.split("\\s+");
109 | for (String address : uris) {
110 | OnvifDevice device = new OnvifDevice(getHostName());
111 | device.addAddress(address);
112 | devices.add(device);
113 | }
114 |
115 | return devices;
116 | }
117 |
118 | private String parseUPnPHeader(String header, String whatSearch) {
119 | String result = "";
120 | int searchLinePos = header.indexOf(whatSearch);
121 | if (searchLinePos != -1) {
122 | searchLinePos += whatSearch.length();
123 | int locColon = header.indexOf(LINE_END, searchLinePos);
124 | result = header.substring(searchLinePos, locColon);
125 | }
126 | return result;
127 | }
128 |
129 |
130 | }
131 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/parsers/GetDeviceInformationParser.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.parsers;
2 |
3 | import be.teletask.onvif.models.OnvifDeviceInformation;
4 | import be.teletask.onvif.responses.OnvifResponse;
5 |
6 | import org.xmlpull.v1.XmlPullParser;
7 | import org.xmlpull.v1.XmlPullParserException;
8 |
9 | import java.io.IOException;
10 | import java.io.StringReader;
11 |
12 | /**
13 | * Created by Tomas Verhelst on 04/09/2018.
14 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
15 | */
16 | public class GetDeviceInformationParser extends OnvifParser {
17 |
18 | //Constants
19 | public static final String TAG = GetDeviceInformationParser.class.getSimpleName();
20 | private static final String KEY_MANUFACTURER = "Manufacturer";
21 | private static final String KEY_MODEL = "Model";
22 | private static final String KEY_FIRMWARE_VERSION = "FirmwareVersion";
23 | private static final String KEY_SERIAL_NUMBER = "SerialNumber";
24 | private static final String KEY_HARDWARE_ID = "HardwareId";
25 |
26 | @Override
27 | public OnvifDeviceInformation parse(OnvifResponse response) {
28 | OnvifDeviceInformation deviceInformation = new OnvifDeviceInformation();
29 |
30 | try {
31 | getXpp().setInput(new StringReader(response.getXml()));
32 | eventType = getXpp().getEventType();
33 | while (eventType != XmlPullParser.END_DOCUMENT) {
34 |
35 | if (eventType == XmlPullParser.START_TAG && getXpp().getName().equals(KEY_MANUFACTURER)) {
36 | getXpp().next();
37 | deviceInformation.setManufacturer(getXpp().getText());
38 | } else if (eventType == XmlPullParser.START_TAG && getXpp().getName().equals(KEY_MODEL)) {
39 | getXpp().next();
40 | deviceInformation.setModel(getXpp().getText());
41 | } else if (eventType == XmlPullParser.START_TAG && getXpp().getName().equals(KEY_FIRMWARE_VERSION)) {
42 | getXpp().next();
43 | deviceInformation.setFirmwareVersion(getXpp().getText());
44 | } else if (eventType == XmlPullParser.START_TAG && getXpp().getName().equals(KEY_SERIAL_NUMBER)) {
45 | getXpp().next();
46 | deviceInformation.setSerialNumber(getXpp().getText());
47 | } else if (eventType == XmlPullParser.START_TAG && getXpp().getName().equals(KEY_HARDWARE_ID)) {
48 | getXpp().next();
49 | deviceInformation.setHardwareId(getXpp().getText());
50 | }
51 | eventType = getXpp().next();
52 |
53 | }
54 | } catch (XmlPullParserException | IOException e) {
55 | e.printStackTrace();
56 | }
57 |
58 | return deviceInformation;
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/parsers/GetMediaProfilesParser.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.parsers;
2 |
3 | import be.teletask.onvif.models.OnvifMediaProfile;
4 | import be.teletask.onvif.responses.OnvifResponse;
5 |
6 | import org.xmlpull.v1.XmlPullParser;
7 | import org.xmlpull.v1.XmlPullParserException;
8 |
9 | import java.io.IOException;
10 | import java.io.StringReader;
11 | import java.util.ArrayList;
12 | import java.util.List;
13 |
14 | /**
15 | * Created by Tomas Verhelst on 04/09/2018.
16 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
17 | */
18 | public class GetMediaProfilesParser extends OnvifParser> {
19 |
20 | //Constants
21 | public static final String TAG = GetMediaProfilesParser.class.getSimpleName();
22 | private static final String KEY_PROFILES = "Profiles";
23 | private static final String ATTR_TOKEN = "token";
24 | private static final String ATTR_NAME = "Name";
25 |
26 | @Override
27 | public List parse(OnvifResponse response) {
28 | List profiles = new ArrayList<>();
29 |
30 | try {
31 | getXpp().setInput(new StringReader(response.getXml()));
32 | eventType = getXpp().getEventType();
33 | while (eventType != XmlPullParser.END_DOCUMENT) {
34 |
35 | if (eventType == XmlPullParser.START_TAG && getXpp().getName().equals(KEY_PROFILES)) {
36 |
37 | String token = getXpp().getAttributeValue(null, ATTR_TOKEN);
38 | getXpp().nextTag();
39 | if (getXpp().getName().equals(ATTR_NAME)) {
40 | getXpp().next();
41 | String name = getXpp().getText();
42 | profiles.add(new OnvifMediaProfile(name, token));
43 | }
44 | }
45 | eventType = getXpp().next();
46 | }
47 | } catch (XmlPullParserException | IOException e) {
48 | e.printStackTrace();
49 | }
50 |
51 | return profiles;
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/parsers/GetMediaStreamParser.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.parsers;
2 |
3 | import be.teletask.onvif.responses.OnvifResponse;
4 |
5 | import org.xmlpull.v1.XmlPullParser;
6 | import org.xmlpull.v1.XmlPullParserException;
7 |
8 | import java.io.IOException;
9 | import java.io.StringReader;
10 |
11 | /**
12 | * Created by Tomas Verhelst on 04/09/2018.
13 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
14 | */
15 | public class GetMediaStreamParser extends OnvifParser {
16 |
17 | //Constants
18 | public static final String TAG = GetMediaStreamParser.class.getSimpleName();
19 | private static final String KEY_URI = "Uri";
20 |
21 | @Override
22 | public String parse(OnvifResponse response) {
23 | String uri = "";
24 | try {
25 | getXpp().setInput(new StringReader(response.getXml()));
26 | eventType = getXpp().getEventType();
27 | while (eventType != XmlPullParser.END_DOCUMENT) {
28 |
29 | if (eventType == XmlPullParser.START_TAG && getXpp().getName().equals(KEY_URI)) {
30 |
31 | getXpp().next();
32 | uri = getXpp().getText();
33 | break;
34 | }
35 | eventType = getXpp().next();
36 | }
37 | } catch (XmlPullParserException | IOException e) {
38 | e.printStackTrace();
39 | }
40 |
41 | return uri;
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/parsers/GetServicesParser.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.parsers;
2 |
3 | import be.teletask.onvif.OnvifUtils;
4 | import be.teletask.onvif.models.OnvifServices;
5 | import be.teletask.onvif.models.OnvifType;
6 | import be.teletask.onvif.responses.OnvifResponse;
7 |
8 | import org.xmlpull.v1.XmlPullParser;
9 | import org.xmlpull.v1.XmlPullParserException;
10 |
11 | import java.io.IOException;
12 | import java.io.StringReader;
13 |
14 | /**
15 | * Created by Tomas Verhelst on 04/09/2018.
16 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
17 | */
18 | public class GetServicesParser extends OnvifParser {
19 |
20 | @Override
21 | public OnvifServices parse(OnvifResponse response) {
22 | OnvifServices path = new OnvifServices();
23 |
24 | try {
25 | getXpp().setInput(new StringReader(response.getXml()));
26 | eventType = getXpp().getEventType();
27 | while (eventType != XmlPullParser.END_DOCUMENT) {
28 |
29 | if (eventType == XmlPullParser.START_TAG && getXpp().getName().equals("Namespace")) {
30 | getXpp().next();
31 | String currentNamespace = getXpp().getText();
32 |
33 | if (currentNamespace.equals(OnvifType.GET_DEVICE_INFORMATION.namespace)) {
34 | String uri = OnvifUtils.retrieveXAddr(getXpp());
35 | path.setDeviceInformationPath(OnvifUtils.getPathFromURL(uri));
36 | } else if (currentNamespace.equals(OnvifType.GET_MEDIA_PROFILES.namespace)
37 | || currentNamespace.equals(OnvifType.GET_STREAM_URI.namespace)) {
38 | String uri = OnvifUtils.retrieveXAddr(getXpp());
39 | path.setProfilesPath(OnvifUtils.getPathFromURL(uri));
40 | path.setStreamURIPath(OnvifUtils.getPathFromURL(uri));
41 | }
42 | }
43 |
44 | eventType = getXpp().next();
45 | }
46 | } catch (XmlPullParserException | IOException e) {
47 | e.printStackTrace();
48 | }
49 |
50 | return path;
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/parsers/OnvifParser.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.parsers;
2 |
3 | import be.teletask.onvif.responses.OnvifResponse;
4 |
5 | import org.xmlpull.v1.XmlPullParser;
6 | import org.xmlpull.v1.XmlPullParserException;
7 | import org.xmlpull.v1.XmlPullParserFactory;
8 |
9 | /**
10 | * Created by Tomas Verhelst on 03/09/2018.
11 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
12 | */
13 | public abstract class OnvifParser {
14 |
15 | //Constants
16 | public static final String TAG = OnvifParser.class.getSimpleName();
17 |
18 | //Attributes
19 | private XmlPullParserFactory xmlFactory;
20 | private XmlPullParser xpp;
21 | int eventType;
22 |
23 | //Constructors
24 |
25 | OnvifParser() {
26 | try {
27 | xmlFactory = XmlPullParserFactory.newInstance();
28 | xmlFactory.setNamespaceAware(true);
29 | xpp = xmlFactory.newPullParser();
30 | } catch (XmlPullParserException e) {
31 | e.printStackTrace();
32 | }
33 | }
34 |
35 | //Properties
36 | protected XmlPullParserFactory getXmlFactory() {
37 | return xmlFactory;
38 | }
39 |
40 | protected void setXmlFactory(XmlPullParserFactory xmlFactory) {
41 | this.xmlFactory = xmlFactory;
42 | }
43 |
44 | XmlPullParser getXpp() {
45 | return xpp;
46 | }
47 |
48 | public abstract T parse(OnvifResponse response);
49 | }
50 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/parsers/UPnPParser.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.parsers;
2 |
3 | import be.teletask.onvif.responses.OnvifResponse;
4 | import be.teletask.onvif.upnp.UPnPDeviceInformation;
5 |
6 | import org.xmlpull.v1.XmlPullParser;
7 | import org.xmlpull.v1.XmlPullParserException;
8 |
9 | import java.io.IOException;
10 | import java.io.StringReader;
11 |
12 | /**
13 | * Created by Tomas Verhelst on 06/09/2018.
14 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
15 | */
16 | public class UPnPParser extends OnvifParser {
17 |
18 | //Constants
19 | public static final String TAG = UPnPParser.class.getSimpleName();
20 | private static final String KEY_DEVICE_TYPE = "deviceType";
21 | private static final String KEY_FRIENDLY_NAME = "friendlyName";
22 | private static final String KEY_MANUFACTURER = "manufacturer";
23 | private static final String KEY_MANUFACTURER_URL = "manufacturerURL";
24 | private static final String KEY_MODEL_DESCRIPTION = "modelDescription";
25 | private static final String KEY_MODEL_NAME = "modelName";
26 | private static final String KEY_MODEL_NUMBER = "modelNumber";
27 | private static final String KEY_MODEL_URL = "modelURL";
28 | private static final String KEY_SERIAL_NUMBER = "serialNumber";
29 | private static final String KEY_UDN = "UDN";
30 | private static final String KEY_PRESENTATION_URL = "presentationURL";
31 | private static final String KEY_URL_BASE = "URLBase";
32 |
33 | //Attributes
34 |
35 | @Override
36 | public UPnPDeviceInformation parse(OnvifResponse response) {
37 | UPnPDeviceInformation deviceInformation = new UPnPDeviceInformation();
38 |
39 | try {
40 | getXpp().setInput(new StringReader(response.getXml()));
41 | eventType = getXpp().getEventType();
42 | while (eventType != XmlPullParser.END_DOCUMENT) {
43 |
44 | if (eventType == XmlPullParser.START_TAG && getXpp().getName().equals(KEY_DEVICE_TYPE)) {
45 | getXpp().next();
46 | deviceInformation.setDeviceType(getXpp().getText());
47 | } else if (eventType == XmlPullParser.START_TAG && getXpp().getName().equals(KEY_FRIENDLY_NAME)) {
48 | getXpp().next();
49 | deviceInformation.setFriendlyName(getXpp().getText());
50 | } else if (eventType == XmlPullParser.START_TAG && getXpp().getName().equals(KEY_MANUFACTURER)) {
51 | getXpp().next();
52 | deviceInformation.setManufacturer(getXpp().getText());
53 | } else if (eventType == XmlPullParser.START_TAG && getXpp().getName().equals(KEY_MANUFACTURER_URL)) {
54 | getXpp().next();
55 | deviceInformation.setManufacturerURL(getXpp().getText());
56 | } else if (eventType == XmlPullParser.START_TAG && getXpp().getName().equals(KEY_MODEL_DESCRIPTION)) {
57 | getXpp().next();
58 | deviceInformation.setModelDescription(getXpp().getText());
59 | } else if (eventType == XmlPullParser.START_TAG && getXpp().getName().equals(KEY_MODEL_NAME)) {
60 | getXpp().next();
61 | deviceInformation.setModelName(getXpp().getText());
62 | } else if (eventType == XmlPullParser.START_TAG && getXpp().getName().equals(KEY_MODEL_NUMBER)) {
63 | getXpp().next();
64 | deviceInformation.setModelNumber(getXpp().getText());
65 | } else if (eventType == XmlPullParser.START_TAG && getXpp().getName().equals(KEY_MODEL_URL)) {
66 | getXpp().next();
67 | deviceInformation.setModelURL(getXpp().getText());
68 | } else if (eventType == XmlPullParser.START_TAG && getXpp().getName().equals(KEY_SERIAL_NUMBER)) {
69 | getXpp().next();
70 | deviceInformation.setSerialNumber(getXpp().getText());
71 | } else if (eventType == XmlPullParser.START_TAG && getXpp().getName().equals(KEY_UDN)) {
72 | getXpp().next();
73 | deviceInformation.setUDN(getXpp().getText());
74 | } else if (eventType == XmlPullParser.START_TAG && getXpp().getName().equals(KEY_PRESENTATION_URL)) {
75 | getXpp().next();
76 | deviceInformation.setPresentationURL(getXpp().getText());
77 | } else if (eventType == XmlPullParser.START_TAG && getXpp().getName().equals(KEY_URL_BASE)) {
78 | getXpp().next();
79 | deviceInformation.setUrlBase(getXpp().getText());
80 | }
81 |
82 | eventType = getXpp().next();
83 | }
84 | } catch (XmlPullParserException | IOException e) {
85 | e.printStackTrace();
86 | }
87 |
88 | return deviceInformation;
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/requests/GetDeviceInformationRequest.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.requests;
2 |
3 | import be.teletask.onvif.listeners.OnvifDeviceInformationListener;
4 | import be.teletask.onvif.models.OnvifType;
5 |
6 |
7 | /**
8 | * Created by Tomas Verhelst on 04/09/2018.
9 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
10 | */
11 | public class GetDeviceInformationRequest implements OnvifRequest {
12 |
13 | //Constants
14 | public static final String TAG = GetDeviceInformationRequest.class.getSimpleName();
15 |
16 | //Attributes
17 | private final OnvifDeviceInformationListener listener;
18 |
19 | //Constructors
20 | public GetDeviceInformationRequest(OnvifDeviceInformationListener listener) {
21 | super();
22 | this.listener = listener;
23 | }
24 |
25 | //Properties
26 |
27 | public OnvifDeviceInformationListener getListener() {
28 | return listener;
29 | }
30 |
31 | @Override
32 | public String getXml() {
33 | return "" + "";
34 | }
35 |
36 | @Override
37 | public OnvifType getType() {
38 | return OnvifType.GET_DEVICE_INFORMATION;
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/requests/GetMediaProfilesRequest.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.requests;
2 |
3 | import be.teletask.onvif.listeners.OnvifMediaProfilesListener;
4 | import be.teletask.onvif.models.OnvifType;
5 |
6 |
7 | /**
8 | * Created by Tomas Verhelst on 04/09/2018.
9 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
10 | */
11 | public class GetMediaProfilesRequest implements OnvifRequest {
12 |
13 | //Constants
14 | public static final String TAG = GetMediaProfilesRequest.class.getSimpleName();
15 |
16 | //Attributes
17 | private final OnvifMediaProfilesListener listener;
18 |
19 | //Constructors
20 | public GetMediaProfilesRequest(OnvifMediaProfilesListener listener) {
21 | super();
22 | this.listener = listener;
23 | }
24 |
25 | //Properties
26 |
27 | public OnvifMediaProfilesListener getListener() {
28 | return listener;
29 | }
30 |
31 | @Override
32 | public String getXml() {
33 | return "";
34 | }
35 |
36 | @Override
37 | public OnvifType getType() {
38 | return OnvifType.GET_MEDIA_PROFILES;
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/requests/GetMediaStreamRequest.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.requests;
2 |
3 | import be.teletask.onvif.listeners.OnvifMediaStreamURIListener;
4 | import be.teletask.onvif.models.OnvifMediaProfile;
5 | import be.teletask.onvif.models.OnvifType;
6 |
7 |
8 | /**
9 | * Created by Tomas Verhelst on 04/09/2018.
10 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
11 | */
12 | public class GetMediaStreamRequest implements OnvifRequest {
13 |
14 | //Constants
15 | public static final String TAG = GetMediaStreamRequest.class.getSimpleName();
16 |
17 | //Attributes
18 | private final OnvifMediaProfile mediaProfile;
19 | private final OnvifMediaStreamURIListener listener;
20 |
21 | //Constructors
22 | public GetMediaStreamRequest(OnvifMediaProfile mediaProfile, OnvifMediaStreamURIListener listener) {
23 | super();
24 | this.mediaProfile = mediaProfile;
25 | this.listener = listener;
26 | }
27 |
28 | //Properties
29 |
30 | public OnvifMediaProfile getMediaProfile() {
31 | return mediaProfile;
32 | }
33 |
34 | public OnvifMediaStreamURIListener getListener() {
35 | return listener;
36 | }
37 |
38 | @Override
39 | public String getXml() {
40 | return ""
41 | + ""
42 | + "RTP-Unicast"
43 | + "RTSP"
44 | + ""
45 | + "" + mediaProfile.getToken() + ""
46 | + "";
47 | }
48 |
49 | @Override
50 | public OnvifType getType() {
51 | return OnvifType.GET_STREAM_URI;
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/requests/GetServicesRequest.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.requests;
2 |
3 | import be.teletask.onvif.listeners.OnvifServicesListener;
4 | import be.teletask.onvif.models.OnvifType;
5 |
6 |
7 | /**
8 | * Created by Tomas Verhelst on 04/09/2018.
9 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
10 | */
11 | public class GetServicesRequest implements OnvifRequest {
12 |
13 | //Constants
14 | public static final String TAG = GetServicesRequest.class.getSimpleName();
15 |
16 | //Attributes
17 | private final OnvifServicesListener listener;
18 |
19 | //Constructors
20 | public GetServicesRequest(OnvifServicesListener listener) {
21 | super();
22 | this.listener = listener;
23 | }
24 |
25 | //Properties
26 |
27 | public OnvifServicesListener getListener() {
28 | return listener;
29 | }
30 |
31 | @Override
32 | public String getXml() {
33 | return "" +
34 | "false" +
35 | "";
36 | }
37 |
38 | @Override
39 | public OnvifType getType() {
40 | return OnvifType.GET_SERVICES;
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/requests/OnvifRequest.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.requests;
2 |
3 | import be.teletask.onvif.models.OnvifType;
4 |
5 | /**
6 | * Created by Tomas Verhelst on 03/09/2018.
7 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
8 | */
9 | public interface OnvifRequest {
10 |
11 | String getXml();
12 |
13 | OnvifType getType();
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/responses/OnvifResponse.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.responses;
2 |
3 | import be.teletask.onvif.requests.OnvifRequest;
4 |
5 | /**
6 | * Created by Tomas Verhelst on 03/09/2018.
7 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
8 | */
9 | public class OnvifResponse {
10 |
11 | //Constants
12 | public static final String TAG = OnvifResponse.class.getSimpleName();
13 |
14 | //Attributes
15 | private boolean success;
16 | private int errorCode;
17 | private String errorMessage;
18 | private String xml;
19 |
20 | private OnvifRequest onvifRequest;
21 |
22 | //Constructors
23 | public OnvifResponse(String xml) {
24 | this.xml = xml;
25 | }
26 |
27 | public OnvifResponse(OnvifRequest onvifRequest) {
28 | this.onvifRequest = onvifRequest;
29 | }
30 |
31 | //Properties
32 |
33 | public boolean isSuccess() {
34 | return success;
35 | }
36 |
37 | public void setSuccess(boolean success) {
38 | this.success = success;
39 | }
40 |
41 | public int getErrorCode() {
42 | return errorCode;
43 | }
44 |
45 | public void setErrorCode(int errorCode) {
46 | this.errorCode = errorCode;
47 | }
48 |
49 | public String getErrorMessage() {
50 | return errorMessage;
51 | }
52 |
53 | public void setErrorMessage(String errorMessage) {
54 | this.errorMessage = errorMessage;
55 | }
56 |
57 | public String getXml() {
58 | return xml;
59 | }
60 |
61 | public void setXml(String xml) {
62 | this.xml = xml;
63 | }
64 |
65 | public OnvifRequest request() {
66 | return onvifRequest;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/upnp/UPnPDeviceInformation.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.upnp;
2 |
3 | /**
4 | * Created by Tomas Verhelst on 03/09/2018.
5 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
6 | */
7 | public class UPnPDeviceInformation {
8 |
9 | //Constants
10 | public static final String TAG = UPnPDeviceInformation.class.getSimpleName();
11 |
12 | //Attributes
13 |
14 | //Constructors
15 | private String deviceType;
16 | private String friendlyName;
17 | private String serialNumber;
18 | private String modelDescription;
19 | private String modelName;
20 | private String modelNumber;
21 | private String modelURL;
22 | private String manufacturer;
23 | private String manufacturerURL;
24 | private String UDN;
25 | private String presentationURL;
26 | private String urlBase;
27 |
28 | //Constructors
29 | public UPnPDeviceInformation() {
30 | }
31 |
32 | //Properties
33 |
34 | public String getDeviceType() {
35 | return deviceType;
36 | }
37 |
38 | public void setDeviceType(String deviceType) {
39 | this.deviceType = deviceType;
40 | }
41 |
42 | public String getFriendlyName() {
43 | return friendlyName;
44 | }
45 |
46 | public void setFriendlyName(String friendlyName) {
47 | this.friendlyName = friendlyName;
48 | }
49 |
50 | public String getPresentationURL() {
51 | return presentationURL;
52 | }
53 |
54 | public void setPresentationURL(String presentationURL) {
55 | this.presentationURL = presentationURL;
56 | }
57 |
58 | public String getModelDescription() {
59 | return modelDescription;
60 | }
61 |
62 | public void setModelDescription(String modelDescription) {
63 | this.modelDescription = modelDescription;
64 | }
65 |
66 | public String getSerialNumber() {
67 | return serialNumber;
68 | }
69 |
70 | public void setSerialNumber(String serialNumber) {
71 | this.serialNumber = serialNumber;
72 | }
73 |
74 | public String getModelName() {
75 | return modelName;
76 | }
77 |
78 | public void setModelName(String modelName) {
79 | this.modelName = modelName;
80 | }
81 |
82 | public String getModelNumber() {
83 | return modelNumber;
84 | }
85 |
86 | public void setModelNumber(String modelNumber) {
87 | this.modelNumber = modelNumber;
88 | }
89 |
90 | public String getModelURL() {
91 | return modelURL;
92 | }
93 |
94 | public void setModelURL(String modelURL) {
95 | this.modelURL = modelURL;
96 | }
97 |
98 | public String getManufacturer() {
99 | return manufacturer;
100 | }
101 |
102 | public void setManufacturer(String manufacturer) {
103 | this.manufacturer = manufacturer;
104 | }
105 |
106 | public String getManufacturerURL() {
107 | return manufacturerURL;
108 | }
109 |
110 | public void setManufacturerURL(String manufacturerURL) {
111 | this.manufacturerURL = manufacturerURL;
112 | }
113 |
114 | public String getUDN() {
115 | return UDN;
116 | }
117 |
118 | public void setUDN(String UDN) {
119 | this.UDN = UDN;
120 | }
121 |
122 | public String getUrlBase() {
123 | return urlBase;
124 | }
125 |
126 | public void setUrlBase(String urlBase) {
127 | this.urlBase = urlBase;
128 | }
129 |
130 | @Override
131 | public String toString() {
132 | return "UPnPDeviceInformation{" +
133 | "deviceType='" + deviceType + '\'' +
134 | ", friendlyName='" + friendlyName + '\'' +
135 | ", serialNumber='" + serialNumber + '\'' +
136 | ", modelDescription='" + modelDescription + '\'' +
137 | ", modelName='" + modelName + '\'' +
138 | ", modelNumber='" + modelNumber + '\'' +
139 | ", modelURL='" + modelURL + '\'' +
140 | ", manufacturer='" + manufacturer + '\'' +
141 | ", manufacturerURL='" + manufacturerURL + '\'' +
142 | ", UDN='" + UDN + '\'' +
143 | ", presentationURL='" + presentationURL + '\'' +
144 | ", urlBase='" + urlBase + '\'' +
145 | '}';
146 | }
147 |
148 | }
149 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/upnp/UPnPDeviceInformationListener.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.upnp;
2 |
3 | import be.teletask.onvif.models.UPnPDevice;
4 |
5 |
6 | /**
7 | * Created by Tomas Verhelst on 03/09/2018.
8 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
9 | */
10 | public interface UPnPDeviceInformationListener {
11 |
12 | void onDeviceInformationReceived(UPnPDevice device, UPnPDeviceInformation deviceInformation);
13 |
14 | void onError(UPnPDevice onvifDevice, int errorCode, String errorMessage);
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/upnp/UPnPExecutor.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.upnp;
2 |
3 | import be.teletask.onvif.models.UPnPDevice;
4 | import be.teletask.onvif.parsers.UPnPParser;
5 | import be.teletask.onvif.responses.OnvifResponse;
6 | import okhttp3.*;
7 | import okio.Buffer;
8 |
9 |
10 | import java.io.IOException;
11 | import java.util.concurrent.TimeUnit;
12 |
13 | /**
14 | * Created by Tomas Verhelst on 03/09/2018.
15 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
16 | */
17 | public class UPnPExecutor {
18 |
19 | //Constants
20 | public static final String TAG = UPnPExecutor.class.getSimpleName();
21 |
22 | //Attributes
23 | private OkHttpClient client;
24 | private UPnPResponseListener responseListener;
25 |
26 | //Constructors
27 |
28 | UPnPExecutor(UPnPResponseListener responseListener) {
29 | this.responseListener = responseListener;
30 |
31 | client = new OkHttpClient.Builder()
32 | .connectTimeout(10000, TimeUnit.SECONDS)
33 | .writeTimeout(100, TimeUnit.SECONDS)
34 | .readTimeout(10000, TimeUnit.SECONDS)
35 | .build();
36 | }
37 |
38 | //Methods
39 |
40 | /**
41 | * Sends a request to a UPnP device.
42 | */
43 | public void sendRequest(UPnPDevice device) {
44 | performXmlRequest(device, buildUPnPRequest(device));
45 | }
46 |
47 | /**
48 | * Sends a request to a UPnP device.
49 | */
50 | void getDeviceInformation(UPnPDevice device, UPnPDeviceInformationListener listener) {
51 | Request request = buildUPnPRequest(device);
52 | client.newCall(request)
53 | .enqueue(new Callback() {
54 |
55 | @Override
56 | public void onResponse(Call call, Response xmlResponse) throws IOException {
57 | ResponseBody xmlBody = xmlResponse.body();
58 |
59 | if (xmlResponse.code() == 200 && xmlBody != null) {
60 | UPnPDeviceInformation information = parseDeviceInformation(device, xmlBody.string());
61 | device.setDeviceInformation(information);
62 | listener.onDeviceInformationReceived(device, information);
63 | return;
64 | }
65 |
66 | String errorMessage = "";
67 | if (xmlBody != null)
68 | errorMessage = xmlBody.string();
69 |
70 | listener.onError(device, xmlResponse.code(), errorMessage);
71 | }
72 |
73 | @Override
74 | public void onFailure(Call call, IOException e) {
75 | listener.onError(device, -1, e.getMessage());
76 | }
77 |
78 | });
79 | }
80 |
81 | /**
82 | * Clears up the resources.
83 | */
84 | public void clear() {
85 | responseListener = null;
86 | }
87 |
88 | //Properties
89 |
90 | public void setResponseListener(UPnPResponseListener responseListener) {
91 | this.responseListener = responseListener;
92 | }
93 |
94 | private void performXmlRequest(UPnPDevice device, Request xmlRequest) {
95 | if (xmlRequest == null)
96 | return;
97 |
98 | client.newCall(xmlRequest)
99 | .enqueue(new Callback() {
100 |
101 | @Override
102 | public void onResponse(Call call, Response xmlResponse) throws IOException {
103 | ResponseBody xmlBody = xmlResponse.body();
104 |
105 | if (xmlResponse.code() == 200 && xmlBody != null) {
106 | parseResponse(device, xmlBody.string());
107 | return;
108 | }
109 |
110 | String errorMessage = "";
111 | if (xmlBody != null)
112 | errorMessage = xmlBody.string();
113 |
114 | responseListener.onError(device, xmlResponse.code(), errorMessage);
115 | }
116 |
117 | @Override
118 | public void onFailure(Call call, IOException e) {
119 | responseListener.onError(device, -1, e.getMessage());
120 | }
121 |
122 | });
123 | }
124 |
125 | private UPnPDeviceInformation parseDeviceInformation(UPnPDevice device, String xmlBody) {
126 | return new UPnPParser().parse(new OnvifResponse(xmlBody));
127 | }
128 |
129 | private void parseResponse(UPnPDevice device, String xmlBody) {
130 | UPnPParser parser = new UPnPParser();
131 | parser.parse(new OnvifResponse(xmlBody));
132 | }
133 |
134 | private Request buildUPnPRequest(UPnPDevice device) {
135 | return new Request.Builder()
136 | .url(device.getLocation())
137 | .addHeader("Content-Type", "text/xml; charset=utf-8")
138 | .get()
139 | .build();
140 | }
141 |
142 | private String bodyToString(Request request) {
143 |
144 | try {
145 | Request copy = request.newBuilder().build();
146 | Buffer buffer = new Buffer();
147 | if (copy.body() != null)
148 | copy.body().writeTo(buffer);
149 | return buffer.readUtf8();
150 | } catch (IOException e) {
151 | e.printStackTrace();
152 | return "";
153 | }
154 | }
155 |
156 | }
157 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/upnp/UPnPManager.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.upnp;
2 |
3 | import be.teletask.onvif.models.UPnPDevice;
4 |
5 | import org.jetbrains.annotations.Nullable;
6 |
7 | /**
8 | * Created by Tomas Verhelst on 06/09/2018.
9 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
10 | */
11 | public class UPnPManager implements UPnPResponseListener {
12 |
13 | //Constants
14 | public static final String TAG = UPnPManager.class.getSimpleName();
15 |
16 | //Attributes
17 | private UPnPExecutor executor;
18 | private UPnPResponseListener responseListener;
19 |
20 | //Constructors
21 | public UPnPManager() {
22 | this(null);
23 | }
24 |
25 | private UPnPManager(@Nullable UPnPResponseListener responseListener) {
26 | this.responseListener = responseListener;
27 | executor = new UPnPExecutor(this);
28 | }
29 |
30 | /**
31 | * Gets the device information for a given UPnP device.
32 | * The location attribute of the device should exist.
33 | * This could be filled in manually or from a discovery
34 | *
35 | * @param device
36 | */
37 | public void getDeviceInformation(UPnPDevice device, UPnPDeviceInformationListener listener) {
38 | executor.getDeviceInformation(device, listener);
39 | }
40 |
41 | public void setResponseListener(UPnPResponseListener responseListener) {
42 | this.responseListener = responseListener;
43 | }
44 |
45 | @Override
46 | public void onResponse(UPnPDevice onvifDevice) {
47 |
48 | }
49 |
50 | @Override
51 | public void onError(UPnPDevice onvifDevice, int errorCode, String errorMessage) {
52 |
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/lib/src/main/java/be/teletask/onvif/upnp/UPnPResponseListener.java:
--------------------------------------------------------------------------------
1 | package be.teletask.onvif.upnp;
2 |
3 | import be.teletask.onvif.models.UPnPDevice;
4 |
5 |
6 | /**
7 | * Created by Tomas Verhelst on 03/09/2018.
8 | * Copyright (c) 2018 TELETASK BVBA. All rights reserved.
9 | */
10 | public interface UPnPResponseListener {
11 |
12 | void onResponse(UPnPDevice onvifDevice);
13 |
14 | void onError(UPnPDevice onvifDevice, int errorCode, String errorMessage);
15 | }
16 |
--------------------------------------------------------------------------------