41 | *
42 | *
43 | * @param cs
44 | * the String to check, may be null
45 | * @return {@code true} if only contains digits or is enclosed by blanks, and is non-null
46 | */
47 | public static boolean isIntegerNumber(final String cs) {
48 | if (isEmpty(cs) || !isNumeric(cs.trim())) {
49 | return false;
50 | }
51 | try {
52 | Integer.parseInt(cs.trim());
53 | } catch (NumberFormatException nfe) {
54 | return false;
55 | }
56 | return true;
57 | }
58 |
59 | /**
60 | * Code copied 'as is' from apache-commons-lang3, class StringUtils.isNumeric()
61 | *
62 | *
63 | * Checks if the CharSequence contains only Unicode digits. A decimal point is not a Unicode digit and returns
64 | * false.
65 | *
66 | *
67 | *
68 | * {@code null} will return {@code false}. An empty CharSequence (length()=0) will return {@code false}.
69 | *
70 | *
71 | *
72 | * Note that the method does not allow for a leading sign, either positive or negative. Also, if a String passes the
73 | * numeric test, it may still generate a NumberFormatException when parsed by Integer.parseInt or Long.parseLong,
74 | * e.g. if the value is outside the range for int or long respectively.
75 | *
122 | *
123 | *
124 | * @param cs
125 | * the CharSequence to check, may be null
126 | * @return {@code true} if the CharSequence is empty or null
127 | */
128 | public static boolean isEmpty(final CharSequence cs) {
129 | return cs == null || cs.length() == 0;
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/src/main/java/com/github/kaklakariada/fritzbox/http/AccessForbiddenException.java:
--------------------------------------------------------------------------------
1 | /**
2 | * A Java API for managing FritzBox HomeAutomation
3 | * Copyright (C) 2017 Christoph Pirkl
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.github.kaklakariada.fritzbox.http;
19 |
20 | public class AccessForbiddenException extends HttpException {
21 |
22 | private static final long serialVersionUID = 1L;
23 |
24 | public AccessForbiddenException(String message, Throwable cause) {
25 | super(message, cause);
26 | }
27 |
28 | public AccessForbiddenException(String message) {
29 | super(message);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/com/github/kaklakariada/fritzbox/http/HttpException.java:
--------------------------------------------------------------------------------
1 | /**
2 | * A Java API for managing FritzBox HomeAutomation
3 | * Copyright (C) 2017 Christoph Pirkl
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.github.kaklakariada.fritzbox.http;
19 |
20 | import com.github.kaklakariada.fritzbox.FritzBoxException;
21 |
22 | public class HttpException extends FritzBoxException {
23 |
24 | private static final long serialVersionUID = 1L;
25 |
26 | public HttpException(String message, Throwable cause) {
27 | super(message, cause);
28 | }
29 |
30 | public HttpException(String message) {
31 | super(message);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/com/github/kaklakariada/fritzbox/http/HttpTemplate.java:
--------------------------------------------------------------------------------
1 | /**
2 | * A Java API for managing FritzBox HomeAutomation
3 | * Copyright (C) 2017 Christoph Pirkl
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.github.kaklakariada.fritzbox.http;
19 |
20 | import java.io.IOException;
21 | import java.util.Map.Entry;
22 |
23 | import org.slf4j.Logger;
24 | import org.slf4j.LoggerFactory;
25 |
26 | import com.github.kaklakariada.fritzbox.FritzBoxException;
27 | import com.github.kaklakariada.fritzbox.mapping.Deserializer;
28 |
29 | import okhttp3.HttpUrl;
30 | import okhttp3.HttpUrl.Builder;
31 | import okhttp3.MediaType;
32 | import okhttp3.OkHttpClient;
33 | import okhttp3.Request;
34 | import okhttp3.RequestBody;
35 | import okhttp3.Response;
36 |
37 | /**
38 | * This class allows executing http requests against a server. Responses are converted using the given
39 | * {@link Deserializer}.
40 | */
41 | public class HttpTemplate {
42 | private static final Logger LOG = LoggerFactory.getLogger(HttpTemplate.class);
43 |
44 | private final OkHttpClient httpClient;
45 | private final HttpUrl baseUrl;
46 | private final Deserializer deserializer;
47 |
48 | public HttpTemplate(String baseUrl) {
49 | this(createUnsafeOkHttpClient(), new Deserializer(), HttpUrl.parse(baseUrl));
50 | }
51 |
52 | HttpTemplate(OkHttpClient httpClient, Deserializer deserializer, HttpUrl baseUrl) {
53 | this.httpClient = httpClient;
54 | this.deserializer = deserializer;
55 | this.baseUrl = baseUrl;
56 | }
57 |
58 | private static OkHttpClient createUnsafeOkHttpClient() {
59 | final okhttp3.OkHttpClient.Builder builder = new OkHttpClient.Builder();
60 | builder.sslSocketFactory(TrustSelfSignedCertificates.getUnsafeSslSocketFactory(), new NullTrustManager());
61 | builder.hostnameVerifier(new NullHostnameVerifier());
62 | return builder.build();
63 | }
64 |
65 | public T get(String path, Class resultType) {
66 | return get(path, QueryParameters.builder().build(), resultType);
67 | }
68 |
69 | public T get(String path, QueryParameters parameters, Class resultType) {
70 | final HttpUrl url = createUrl(path, parameters);
71 | return get(resultType, url);
72 | }
73 |
74 | public T post(String path, QueryParameters parameters, Class resultType) {
75 | final HttpUrl url = createUrl(path, parameters);
76 | return post(resultType, url);
77 | }
78 |
79 | private T get(Class resultType, HttpUrl url) {
80 | final Request request = new Request.Builder().url(url).get().build();
81 | final Response response = execute(request);
82 | return parse(response, resultType);
83 | }
84 |
85 | private T post(Class resultType, HttpUrl url) {
86 | final MediaType mediaType = MediaType.parse("application/xml");
87 | final RequestBody emptyBody = RequestBody.create(new byte[0], mediaType);
88 | final Request request = new Request.Builder().url(url).post(emptyBody).build();
89 | final Response response = execute(request);
90 | return parse(response, resultType);
91 | }
92 |
93 | private T parse(final Response response, Class resultType) {
94 | if (!response.isSuccessful()) {
95 | throw new FritzBoxException("Request failed: " + response);
96 | }
97 | if (response.code() == 500) {
98 | throw new FritzBoxException("Request failed: " + deserializer.getStringFromStream(response.body().byteStream()));
99 | }
100 | return deserializer.parse(response.body().byteStream(), resultType);
101 | }
102 |
103 | private HttpUrl createUrl(String path, QueryParameters parameters) {
104 | final Builder builder = baseUrl.newBuilder().encodedPath(path);
105 | for (final Entry param : parameters.getParameters().entrySet()) {
106 | builder.addQueryParameter(param.getKey(), param.getValue());
107 | }
108 | return builder.build();
109 | }
110 |
111 | private Response execute(Request request) {
112 | LOG.trace("Executing request {}", request);
113 | try {
114 | final Response response = httpClient.newCall(request).execute();
115 | if (!response.isSuccessful()) {
116 | if (response.code() == 403) {
117 | throw new AccessForbiddenException(
118 | "Authentication failed, session id outdated or invalid: " + response);
119 | }
120 | throw new HttpException("Request failed with response " + response);
121 | }
122 | return response;
123 | } catch (final IOException e) {
124 | throw new HttpException("Error executing requst " + request, e);
125 | }
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/src/main/java/com/github/kaklakariada/fritzbox/http/NullHostnameVerifier.java:
--------------------------------------------------------------------------------
1 | /**
2 | * A Java API for managing FritzBox HomeAutomation
3 | * Copyright (C) 2017 Christoph Pirkl
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.github.kaklakariada.fritzbox.http;
19 |
20 | import javax.net.ssl.HostnameVerifier;
21 | import javax.net.ssl.SSLSession;
22 |
23 | import org.slf4j.Logger;
24 | import org.slf4j.LoggerFactory;
25 |
26 | public class NullHostnameVerifier implements HostnameVerifier {
27 | private static final Logger LOG = LoggerFactory.getLogger(NullHostnameVerifier.class);
28 |
29 | @Override
30 | public boolean verify(String hostname, SSLSession session) {
31 | LOG.trace("Ignore ssl certificate for {}: {}", hostname, session);
32 | return true;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/github/kaklakariada/fritzbox/http/NullTrustManager.java:
--------------------------------------------------------------------------------
1 | /**
2 | * A Java API for managing FritzBox HomeAutomation
3 | * Copyright (C) 2017 Christoph Pirkl
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.github.kaklakariada.fritzbox.http;
19 |
20 | import java.security.cert.X509Certificate;
21 |
22 | import javax.net.ssl.X509TrustManager;
23 |
24 | import org.slf4j.Logger;
25 | import org.slf4j.LoggerFactory;
26 |
27 | class NullTrustManager implements X509TrustManager {
28 | private static final Logger LOG = LoggerFactory.getLogger(NullTrustManager.class);
29 |
30 | // Don't throw exception, we want to accept any certificate
31 | @SuppressWarnings("squid:S4424")
32 | @Override
33 | public void checkClientTrusted(final X509Certificate[] xcs, final String authType) {
34 | LOG.trace("Check client trusted auth type '{}'", authType);
35 | }
36 |
37 | // Don't throw exception, we want to accept any certificate
38 | @SuppressWarnings("squid:S4424")
39 | @Override
40 | public void checkServerTrusted(final X509Certificate[] xcs, final String authType) {
41 | LOG.trace("Check server trusted auth type '{}'", authType);
42 | }
43 |
44 | @Override
45 | public X509Certificate[] getAcceptedIssuers() {
46 | LOG.trace("Get accepted issuers");
47 | return new X509Certificate[0];
48 | }
49 | }
--------------------------------------------------------------------------------
/src/main/java/com/github/kaklakariada/fritzbox/http/QueryParameters.java:
--------------------------------------------------------------------------------
1 | /**
2 | * A Java API for managing FritzBox HomeAutomation
3 | * Copyright (C) 2017 Christoph Pirkl
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.github.kaklakariada.fritzbox.http;
19 |
20 | import java.util.HashMap;
21 | import java.util.Map;
22 |
23 | public class QueryParameters {
24 |
25 | private final Map parameters;
26 |
27 | private QueryParameters(Map parameters) {
28 | this.parameters = parameters;
29 | }
30 |
31 | public static Builder builder() {
32 | return new Builder();
33 | }
34 |
35 | public Map getParameters() {
36 | return parameters;
37 | }
38 |
39 | public Builder newBuilder() {
40 | return new Builder(new HashMap<>(this.parameters));
41 | }
42 |
43 | public static class Builder {
44 | private final Map parameters;
45 |
46 | private Builder() {
47 | this(new HashMap());
48 | }
49 |
50 | public Builder(Map parameters) {
51 | this.parameters = parameters;
52 | }
53 |
54 | public Builder add(String name, String value) {
55 | parameters.put(name, value);
56 | return this;
57 | }
58 |
59 | public QueryParameters build() {
60 | return new QueryParameters(parameters);
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/main/java/com/github/kaklakariada/fritzbox/http/TrustSelfSignedCertificates.java:
--------------------------------------------------------------------------------
1 | /**
2 | * A Java API for managing FritzBox HomeAutomation
3 | * Copyright (C) 2017 Christoph Pirkl
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.github.kaklakariada.fritzbox.http;
19 |
20 | import java.security.KeyManagementException;
21 | import java.security.NoSuchAlgorithmException;
22 | import java.security.SecureRandom;
23 |
24 | import javax.net.ssl.KeyManager;
25 | import javax.net.ssl.SSLContext;
26 | import javax.net.ssl.SSLSocketFactory;
27 | import javax.net.ssl.TrustManager;
28 |
29 | /**
30 | * This class creates an {@link SSLSocketFactory} that trusts all certificates.
31 | *
32 | * @see #getUnsafeSslSocketFactory()
33 | */
34 | public class TrustSelfSignedCertificates {
35 |
36 | private TrustSelfSignedCertificates() {
37 | // Not instantiable
38 | }
39 |
40 | public static SSLSocketFactory getUnsafeSslSocketFactory() {
41 | final SSLContext sslContext = getSSLContext("TLS");
42 | initializeSslContext(sslContext);
43 | return sslContext.getSocketFactory();
44 | }
45 |
46 | private static void initializeSslContext(SSLContext sslContext) {
47 | final KeyManager[] keyManagers = null;
48 | final TrustManager[] trustManagers = new TrustManager[] { new NullTrustManager() };
49 | final SecureRandom secureRandom = new SecureRandom();
50 | final SSLContext sslContext1 = sslContext;
51 | try {
52 | sslContext1.init(keyManagers, trustManagers, secureRandom);
53 | } catch (final KeyManagementException e) {
54 | throw new HttpException("Error initializing ssl context", e);
55 | }
56 | }
57 |
58 | private static SSLContext getSSLContext(String algorithm) {
59 | try {
60 | return SSLContext.getInstance(algorithm);
61 | } catch (final NoSuchAlgorithmException e) {
62 | throw new HttpException("Algorithm " + algorithm + " not found", e);
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/java/com/github/kaklakariada/fritzbox/login/ChallengeResponse.java:
--------------------------------------------------------------------------------
1 | /**
2 | * A Java API for managing FritzBox HomeAutomation
3 | * Copyright (C) 2017 Christoph Pirkl
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.github.kaklakariada.fritzbox.login;
19 |
20 | public interface ChallengeResponse {
21 | String calculateResponse(final String challenge, final String password);
22 |
23 | static ChallengeResponse getAlgorithm(final String challenge) {
24 | if (challenge.startsWith("2$")) {
25 | return new Pbkdf2ChallengeResponse();
26 | } else {
27 | return new Md5LoginChallengeResponse(new Md5Service());
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/github/kaklakariada/fritzbox/login/Md5LoginChallengeResponse.java:
--------------------------------------------------------------------------------
1 | /**
2 | * A Java API for managing FritzBox HomeAutomation
3 | * Copyright (C) 2017 Christoph Pirkl
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.github.kaklakariada.fritzbox.login;
19 |
20 | class Md5LoginChallengeResponse implements ChallengeResponse {
21 |
22 | private final Md5Service md5Service;
23 |
24 | Md5LoginChallengeResponse(final Md5Service md5Service) {
25 | this.md5Service = md5Service;
26 | }
27 |
28 | @Override
29 | public String calculateResponse(final String challenge, final String password) {
30 | final String text = (challenge + "-" + password);
31 | return challenge + "-" + md5Service.md5(text);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/com/github/kaklakariada/fritzbox/login/Md5Service.java:
--------------------------------------------------------------------------------
1 | /**
2 | * A Java API for managing FritzBox HomeAutomation
3 | * Copyright (C) 2017 Christoph Pirkl
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.github.kaklakariada.fritzbox.login;
19 |
20 | import java.nio.charset.StandardCharsets;
21 | import java.security.MessageDigest;
22 | import java.security.NoSuchAlgorithmException;
23 |
24 | class Md5Service {
25 |
26 | String md5(final String s) {
27 | final MessageDigest digest = getMd5MessageDigest();
28 | final byte[] binary = digest.digest(s.getBytes(StandardCharsets.UTF_16LE));
29 | return buildHexString(binary);
30 | }
31 |
32 | // Concatenating strings in a loop is ok here
33 | @SuppressWarnings("squid:S1643")
34 | private String buildHexString(final byte[] data) {
35 | final StringBuilder hexString = new StringBuilder();
36 | for (final byte aMessageDigest : data) {
37 | String h = Integer.toHexString(0xFF & aMessageDigest);
38 | while (h.length() < 2) {
39 | h = "0" + h;
40 | }
41 | hexString.append(h);
42 | }
43 | return hexString.toString();
44 | }
45 |
46 | @SuppressWarnings("java:S4790") // MD5 still required as fallback
47 | private MessageDigest getMd5MessageDigest() {
48 | try {
49 | return MessageDigest.getInstance("MD5");
50 | } catch (final NoSuchAlgorithmException e) {
51 | throw new AssertionError("Error getting MD5 message digest", e);
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/com/github/kaklakariada/fritzbox/login/Pbkdf2ChallengeResponse.java:
--------------------------------------------------------------------------------
1 | /**
2 | * A Java API for managing FritzBox HomeAutomation
3 | * Copyright (C) 2017 Christoph Pirkl
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.github.kaklakariada.fritzbox.login;
19 |
20 | import java.nio.charset.StandardCharsets;
21 | import java.security.InvalidKeyException;
22 | import java.security.NoSuchAlgorithmException;
23 |
24 | import javax.crypto.Mac;
25 | import javax.crypto.spec.SecretKeySpec;
26 |
27 | /**
28 | * PBKDF2 challenge-response. See
29 | * https://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/AVM_Technical_Note_-_Session_ID_english_2021-05-03.pdf
30 | */
31 | class Pbkdf2ChallengeResponse implements ChallengeResponse {
32 |
33 | @Override
34 | public String calculateResponse(final String challenge, final String password) {
35 | final String[] challengeParts = challenge.split("\\$");
36 | if (challengeParts.length != 5) {
37 | throw new IllegalArgumentException("Challenge '" + challenge + "' has an invalid format");
38 | }
39 | final int iter1 = Integer.parseInt(challengeParts[1]);
40 | final byte[] salt1 = fromHex(challengeParts[2]);
41 | final int iter2 = Integer.parseInt(challengeParts[3]);
42 | final byte[] salt2 = fromHex(challengeParts[4]);
43 | final byte[] hash1 = pbkdf2HmacSha256(password.getBytes(StandardCharsets.UTF_8), salt1, iter1);
44 | final byte[] hash2 = pbkdf2HmacSha256(hash1, salt2, iter2);
45 | return challengeParts[4] + "$" + toHex(hash2);
46 | }
47 |
48 | /** Hex string to bytes */
49 | static byte[] fromHex(final String hexString) {
50 | final int len = hexString.length() / 2;
51 | final byte[] ret = new byte[len];
52 | for (int i = 0; i < len; i++) {
53 | ret[i] = (byte) Short.parseShort(hexString.substring(i * 2, i *
54 | 2 + 2), 16);
55 | }
56 | return ret;
57 | }
58 |
59 | /** Byte array to hex string */
60 | static String toHex(final byte[] bytes) {
61 | final StringBuilder s = new StringBuilder(bytes.length * 2);
62 | for (final byte b : bytes) {
63 | s.append(String.format("%02x", b));
64 | }
65 | return s.toString();
66 | }
67 |
68 | /**
69 | * Create a pbkdf2 HMAC by appling the Hmac iter times as specified. We can't use the Android-internal PBKDF2 here,
70 | * as it only accepts char[] arrays, not bytes (for multi-stage hashing)
71 | */
72 | static byte[] pbkdf2HmacSha256(final byte[] password, final byte[] salt, final int iters) {
73 | final String algorithm = "HmacSHA256";
74 | try {
75 | final Mac sha256mac = Mac.getInstance(algorithm);
76 | sha256mac.init(new SecretKeySpec(password, algorithm));
77 | final byte[] ret = new byte[sha256mac.getMacLength()];
78 | byte[] tmp = new byte[salt.length + 4];
79 | System.arraycopy(salt, 0, tmp, 0, salt.length);
80 | tmp[salt.length + 3] = 1;
81 | for (int i = 0; i < iters; i++) {
82 | tmp = sha256mac.doFinal(tmp);
83 | for (int k = 0; k < ret.length; k++) {
84 | ret[k] ^= tmp[k];
85 | }
86 | }
87 | return ret;
88 | } catch (NoSuchAlgorithmException | InvalidKeyException e) {
89 | throw new IllegalStateException("Failed to calculate HMAC", e);
90 | }
91 | }
92 | }
--------------------------------------------------------------------------------
/src/main/java/com/github/kaklakariada/fritzbox/mapping/Deserializer.java:
--------------------------------------------------------------------------------
1 | /**
2 | * A Java API for managing FritzBox HomeAutomation
3 | * Copyright (C) 2017 Christoph Pirkl
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.github.kaklakariada.fritzbox.mapping;
19 |
20 | import java.io.IOException;
21 | import java.io.InputStream;
22 | import java.nio.charset.StandardCharsets;
23 | import java.util.Scanner;
24 |
25 | import org.simpleframework.xml.Serializer;
26 | import org.simpleframework.xml.core.Persister;
27 | import org.slf4j.Logger;
28 | import org.slf4j.LoggerFactory;
29 |
30 | /**
31 | * This class allows deserializing {@link String}s to a requested type.
32 | */
33 | public class Deserializer {
34 | private static final Logger LOG = LoggerFactory.getLogger(Deserializer.class);
35 |
36 | private final Serializer xmlSerializer;
37 |
38 | public Deserializer() {
39 | this(new Persister());
40 | }
41 |
42 | Deserializer(Serializer xmlSerializer) {
43 | this.xmlSerializer = xmlSerializer;
44 | }
45 |
46 | public T parse(InputStream data, Class resultType) {
47 | try {
48 | final T resultObject;
49 | if (resultType == String.class
50 | || resultType == Boolean.class
51 | || resultType == Integer.class) {
52 | resultObject = parseSimpleType(resultType, data);
53 | } else {
54 | resultObject = xmlSerializer.read(resultType, data);
55 | }
56 | LOG.trace("Parsed response: {}", resultObject);
57 | return resultObject;
58 | } catch (final Exception e) {
59 | throw new DeserializerException("Error parsing response body", e);
60 | }
61 | }
62 |
63 | private T parseSimpleType(Class resultType, InputStream data) throws IOException {
64 | final String string = getStringFromStream(data);
65 | if (resultType == String.class) {
66 | return resultType.cast(string);
67 | } else if (resultType == Boolean.class) {
68 | return resultType.cast("1".equals(string));
69 | } else if (resultType == Integer.class) {
70 | if (string.isEmpty() || "inval".equals(string)) {
71 | return null;
72 | }
73 | return resultType.cast(Integer.parseInt(string));
74 | }
75 | throw new IOException("Type '" + resultType + "' is not supported: " + string);
76 | }
77 |
78 | public String getStringFromStream(InputStream data) {
79 | final Scanner scanner = new Scanner(data, StandardCharsets.UTF_8.toString());
80 | final String string = scanner.next();
81 | scanner.close();
82 | return string;
83 | }
84 |
85 | }
86 |
--------------------------------------------------------------------------------
/src/main/java/com/github/kaklakariada/fritzbox/mapping/DeserializerException.java:
--------------------------------------------------------------------------------
1 | /**
2 | * A Java API for managing FritzBox HomeAutomation
3 | * Copyright (C) 2017 Christoph Pirkl
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.github.kaklakariada.fritzbox.mapping;
19 |
20 | import com.github.kaklakariada.fritzbox.FritzBoxException;
21 |
22 | public class DeserializerException extends FritzBoxException {
23 |
24 | private static final long serialVersionUID = 1L;
25 |
26 | public DeserializerException(String message, Throwable cause) {
27 | super(message, cause);
28 | }
29 |
30 | public DeserializerException(String message) {
31 | super(message);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/com/github/kaklakariada/fritzbox/model/Rights.java:
--------------------------------------------------------------------------------
1 | /**
2 | * A Java API for managing FritzBox HomeAutomation
3 | * Copyright (C) 2017 Christoph Pirkl
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.github.kaklakariada.fritzbox.model;
19 |
20 | import java.util.List;
21 |
22 | import org.simpleframework.xml.ElementList;
23 | import org.simpleframework.xml.Root;
24 |
25 | @Root(name = "Rights")
26 | public class Rights {
27 |
28 | @ElementList(inline = true, required = false, type = UserRight.class)
29 | private List userRights;
30 |
31 | public List getRights() {
32 | return userRights;
33 | }
34 |
35 | @Override
36 | public String toString() {
37 | return "Rights [rights=" + userRights + "]";
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/com/github/kaklakariada/fritzbox/model/SessionInfo.java:
--------------------------------------------------------------------------------
1 | /**
2 | * A Java API for managing FritzBox HomeAutomation
3 | * Copyright (C) 2017 Christoph Pirkl
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.github.kaklakariada.fritzbox.model;
19 |
20 | import java.util.List;
21 |
22 | import org.simpleframework.xml.Element;
23 | import org.simpleframework.xml.ElementList;
24 | import org.simpleframework.xml.Root;
25 |
26 | @Root(name = "SessionInfo")
27 | public class SessionInfo {
28 |
29 | @Element(name = "SID")
30 | private String sid;
31 |
32 | @Element(name = "Challenge")
33 | private String challenge;
34 |
35 | @Element(name = "BlockTime")
36 | private String blockTime;
37 |
38 | @ElementList(name = "Rights", inline = false, required = false)
39 | private List rights;
40 |
41 | @ElementList(name = "Users", inline = false, required = false)
42 | private List users;
43 |
44 | public String getSid() {
45 | return sid;
46 | }
47 |
48 | public String getChallenge() {
49 | return challenge;
50 | }
51 |
52 | public String getBlockTime() {
53 | return blockTime;
54 | }
55 |
56 | public List getRights() {
57 | return rights;
58 | }
59 |
60 | public List getUsers() {
61 | return users;
62 | }
63 |
64 | @Override
65 | public String toString() {
66 | return "SessionInfo [sid=" + sid + ", challenge=" + challenge + ", blockTime=" + blockTime + ", rights="
67 | + rights + "]";
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/main/java/com/github/kaklakariada/fritzbox/model/User.java:
--------------------------------------------------------------------------------
1 | /**
2 | * A Java API for managing FritzBox HomeAutomation
3 | * Copyright (C) 2017 Christoph Pirkl
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.github.kaklakariada.fritzbox.model;
19 |
20 | import org.simpleframework.xml.Attribute;
21 | import org.simpleframework.xml.Text;
22 |
23 | public class User {
24 |
25 | @Attribute(name = "last", required = false)
26 | private int last;
27 |
28 | @Text
29 | private String name;
30 |
31 | public boolean isLast() {
32 | return (last == 1);
33 | }
34 |
35 | public String getName() {
36 | return name;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/com/github/kaklakariada/fritzbox/model/UserRight.java:
--------------------------------------------------------------------------------
1 | /**
2 | * A Java API for managing FritzBox HomeAutomation
3 | * Copyright (C) 2017 Christoph Pirkl
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.github.kaklakariada.fritzbox.model;
19 |
20 | import org.simpleframework.xml.Element;
21 |
22 | public class UserRight {
23 |
24 | @Element(name = "Name", required = false)
25 | private String name;
26 | @Element(name = "Access", required = false)
27 | private int access;
28 |
29 | @Override
30 | public String toString() {
31 | return "UserRight [name=" + name + ", access=" + access + "]";
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/AbstractDeviceStatistics.java:
--------------------------------------------------------------------------------
1 | /**
2 | * A Java API for managing FritzBox HomeAutomation
3 | * Copyright (C) 2017 Christoph Pirkl
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.github.kaklakariada.fritzbox.model.homeautomation;
19 |
20 | import java.util.List;
21 | import java.util.Optional;
22 | import java.util.stream.Collectors;
23 |
24 | public abstract class AbstractDeviceStatistics {
25 |
26 | /**
27 | * Supply the Statistics gathered for a chosen grid
28 | *
29 | * @param grid
30 | * grid
31 | * @return Optional - avoid NPE if no statistics present
32 | */
33 | public Optional getStatisticsByGrid(final int grid) {
34 | return getStats()
35 | .stream()
36 | .filter(stats -> stats.getGrid() == grid)
37 | .findAny();
38 | }
39 |
40 | /**
41 | * All classes implementing this abstract class need to provide a "getStats"-method
42 | *
43 | * @return List
44 | */
45 | public abstract List getStats();
46 |
47 | /**
48 | * AVM gathers just integer numbers. We know the precision only from documentation, it is never provided by returned
49 | * responses from Fritz!Box. So we add this information here to the statistics.
50 | *
51 | * @param stats statistics to which to add the measurment unit
52 | * @param measurementUnit the unit to add to the statistics
53 | * @return statistics with measurement units
54 | */
55 | protected List getStats(final List stats, final MeasurementUnit measurementUnit) {
56 | return stats
57 | .stream()
58 | .map(stat -> {
59 | stat.setMeasurementUnit(measurementUnit);
60 | return stat;
61 | })
62 | .collect(Collectors.toList());
63 | }
64 |
65 | /**
66 | * All classes implementing this abstract class need to provide a "statisticsToString"-method
67 | *
68 | * @return List
69 | */
70 | protected abstract List statisticsToString();
71 |
72 | /**
73 | * @param type statistics type
74 | * @return statistics as one line per grid
75 | */
76 | protected List statisticsToString(final String type) {
77 | return getStats()
78 | .stream()
79 | .map(stats -> statisticsToString(type, stats))
80 | .collect(Collectors.toList());
81 | }
82 |
83 | /**
84 | * Form a line from a single statistic.
85 | *
86 | * @param type statistics type
87 | * @param statistics statistic to convert to {@link String}
88 | * @return statistic as a line
89 | */
90 | private String statisticsToString(final String type, final Statistics statistics) {
91 | return String.format("[%s] count=%s,grid=%s values=[%s]", type, statistics.getCount(), statistics.getGrid(),
92 | statistics.getCsvValues());
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Alert.java:
--------------------------------------------------------------------------------
1 | /**
2 | * A Java API for managing FritzBox HomeAutomation
3 | * Copyright (C) 2017 Christoph Pirkl
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.github.kaklakariada.fritzbox.model.homeautomation;
19 |
20 | import org.simpleframework.xml.Element;
21 | import org.simpleframework.xml.Root;
22 |
23 | @Root(name = "alert")
24 | public class Alert {
25 |
26 | @Element(name = "state", required = false)
27 | private int state;
28 |
29 | @Element(name = "lastalertchgtimestamp", required = false)
30 | private long lastAlertChgTimestamp;
31 |
32 | public int getState() {
33 | return state;
34 | }
35 |
36 | public void setState(int state) {
37 | this.state = state;
38 | }
39 |
40 | public long getLastAlertChgTimestamp() {
41 | return lastAlertChgTimestamp;
42 | }
43 |
44 | public void setLastAlertChgTimestamp(long lastAlertChgTimestamp) {
45 | this.lastAlertChgTimestamp = lastAlertChgTimestamp;
46 | }
47 | }
--------------------------------------------------------------------------------
/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Blind.java:
--------------------------------------------------------------------------------
1 | /**
2 | * A Java API for managing FritzBox HomeAutomation
3 | * Copyright (C) 2017 Christoph Pirkl
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.github.kaklakariada.fritzbox.model.homeautomation;
19 |
20 | import org.simpleframework.xml.Element;
21 | import org.simpleframework.xml.Root;
22 |
23 | @Root(name = "blind")
24 | public class Blind {
25 |
26 | @Element(name = "endpositionsset", required = false)
27 | private int endPositionsSet;
28 |
29 | @Element(name = "mode", required = false)
30 | private String mode;
31 |
32 | public int getEndPositionsSet() {
33 | return endPositionsSet;
34 | }
35 |
36 | public void setEndPositionsSet(int endPositionsSet) {
37 | this.endPositionsSet = endPositionsSet;
38 | }
39 |
40 | public String getMode() {
41 | return mode;
42 | }
43 |
44 | public void setMode(String mode) {
45 | this.mode = mode;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Button.java:
--------------------------------------------------------------------------------
1 | /**
2 | * A Java API for managing FritzBox HomeAutomation
3 | * Copyright (C) 2017 Christoph Pirkl
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.github.kaklakariada.fritzbox.model.homeautomation;
19 |
20 | import org.simpleframework.xml.Attribute;
21 | import org.simpleframework.xml.Element;
22 | import org.simpleframework.xml.Root;
23 |
24 | @Root(name = "button")
25 | public class Button {
26 |
27 | @Attribute(name = "identifier")
28 | private String identifier;
29 | @Attribute(name = "id")
30 | private String id;
31 | @Element(name = "name", required = false)
32 | private String name;
33 | @Element(name = "lastpressedtimestamp", required = false)
34 | private String lastpressedtimestamp;
35 |
36 | public String getIdentifier() {
37 | return identifier;
38 | }
39 |
40 | public String getId() {
41 | return id;
42 | }
43 |
44 | public String getName() {
45 | return name;
46 | }
47 |
48 | public String getLastpressedtimestamp() {
49 | return lastpressedtimestamp;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/ColorControl.java:
--------------------------------------------------------------------------------
1 | /**
2 | * A Java API for managing FritzBox HomeAutomation
3 | * Copyright (C) 2017 Christoph Pirkl
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.github.kaklakariada.fritzbox.model.homeautomation;
19 |
20 | import org.simpleframework.xml.Attribute;
21 | import org.simpleframework.xml.Element;
22 | import org.simpleframework.xml.Root;
23 |
24 | @Root(name = "colorcontrol")
25 | public class ColorControl {
26 | @Element(name = "hue", required = false)
27 | private String hue;
28 |
29 | @Element(name = "saturation", required = false)
30 | private String saturation;
31 |
32 | @Element(name = "temperature", required = false)
33 | private String temperature;
34 |
35 | @Attribute(name = "supported_modes")
36 | private String supportedModes;
37 |
38 | @Attribute(name = "current_mode", required = false)
39 | private String currentMode;
40 |
41 | @Attribute(name = "fullcolorsupport", required = false)
42 | private String fullColorSupport;
43 |
44 | @Attribute(name = "mapped", required = false)
45 | private String mapped;
46 |
47 | @Element(name = "unmapped_hue", required = false)
48 | private String unmappedHue;
49 |
50 | @Element(name = "unmapped_saturation", required = false)
51 | private String unmappedSaturation;
52 |
53 | public String getHue() {
54 | return hue;
55 | }
56 |
57 | public String getSaturation() {
58 | return saturation;
59 | }
60 |
61 | public String getTemperature() {
62 | return temperature;
63 | }
64 |
65 | public String getSupportedModes() {
66 | return supportedModes;
67 | }
68 |
69 | public String getCurrentMode() {
70 | return currentMode;
71 | }
72 |
73 | public String getFullColorSupport() {
74 | return fullColorSupport;
75 | }
76 |
77 | public String getMapped() {
78 | return mapped;
79 | }
80 |
81 | public String getUnmappedHue() {
82 | return unmappedHue;
83 | }
84 |
85 | public String getUnmappedSaturation() {
86 | return unmappedSaturation;
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/main/java/com/github/kaklakariada/fritzbox/model/homeautomation/Device.java:
--------------------------------------------------------------------------------
1 | /**
2 | * A Java API for managing FritzBox HomeAutomation
3 | * Copyright (C) 2017 Christoph Pirkl
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.github.kaklakariada.fritzbox.model.homeautomation;
19 |
20 | import java.util.List;
21 | import java.util.Optional;
22 |
23 | import org.simpleframework.xml.Attribute;
24 | import org.simpleframework.xml.Element;
25 | import org.simpleframework.xml.ElementList;
26 | import org.simpleframework.xml.Root;
27 |
28 | @Root(name = "device")
29 | public class Device {
30 |
31 | @Attribute(name = "identifier", required = true)
32 | private String identifier;
33 | @Attribute(name = "id")
34 | private String id;
35 | @Attribute(name = "functionbitmask")
36 | private int functionBitmask;
37 | @Attribute(name = "fwversion")
38 | private String firmwareVersion;
39 | @Attribute(name = "manufacturer")
40 | private String manufacturer;
41 |
42 | @Attribute(name = "productname")
43 | private String productName;
44 |
45 | @Element(name = "present")
46 | private String present;
47 | @Element(name = "txbusy", required = false)
48 | private String txbusy;
49 | @Element(name = "name")
50 | private String name;
51 |
52 | @Element(name = "batterylow", required = false)
53 | private Integer batterylow;
54 | @Element(name = "battery", required = false)
55 | private Integer battery;
56 | @Element(name = "switch", required = false)
57 | private SwitchState switchState;
58 | @Element(name = "simpleonoff", required = false)
59 | private SimpleOnOffState simpleOnOff;
60 | @Element(name = "powermeter", required = false)
61 | private PowerMeter powerMeter;
62 | @Element(name = "temperature", required = false)
63 | private Temperature temperature;
64 | @Element(name = "hkr", required = false)
65 | private Hkr hkr;
66 | @Element(name = "levelcontrol", required = false)
67 | private LevelControl levelControl;
68 | @Element(name = "colorcontrol", required = false)
69 | private ColorControl colorControl;
70 | @Element(name = "etsiunitinfo", required = false)
71 | private EtsiUnitInfo etsiUnitInfo;
72 | @ElementList(name = "buttons", required = false, inline = true)
73 | private List