]> git.basschouten.com Git - openhab-addons.git/blob
dd66b0a5e4379b6ad7215659fc14d03ddbd6314c
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.androidtv.internal.protocol.googletv;
14
15 import static org.openhab.binding.androidtv.internal.AndroidTVBindingConstants.*;
16 import static org.openhab.binding.androidtv.internal.protocol.googletv.GoogleTVConstants.*;
17
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19
20 /**
21  * Contains static methods for constructing LEAP messages
22  *
23  * @author Ben Rosenblum - Initial contribution
24  */
25 @NonNullByDefault
26 public class GoogleTVRequest {
27
28     public static String encodeMessage(String message) {
29         StringBuilder reply = new StringBuilder();
30         char[] charArray = message.toCharArray();
31         for (int i = 0; i < charArray.length; i = i + 2) {
32             String st = "" + charArray[i] + "" + charArray[i + 1];
33             char ch = (char) Integer.parseInt(st, 16);
34             reply.append(ch);
35         }
36         return reply.toString();
37     }
38
39     public static String decodeMessage(String message) {
40         StringBuilder sb = new StringBuilder();
41         char ch[] = message.toCharArray();
42         for (int i = 0; i < ch.length; i++) {
43             String hexString = Integer.toHexString(ch[i]);
44             if (hexString.length() % 2 > 0) {
45                 sb.append('0');
46             }
47             sb.append(hexString);
48         }
49         return sb.toString();
50     }
51
52     public static String pinRequest(String pin) {
53         // OLD
54         if (PIN_REQUEST.equals(pin)) {
55             return loginRequest(3);
56         } else {
57             // 080210c801c202 22 0a 20 0e066c3d1c3a6686edb6b2648ff25fcb3f0bf9cc81deeee9fad1a26073645e17
58             // 080210c801c202 22 0a 20 530bb7c7ba06069997285aff6e0106adfb19ab23c18a7422f5f643b35a6467b3
59             // -------------------------SHA HASH OF PIN
60
61             int length = pin.length() / 2;
62             String len1 = GoogleTVRequest.fixMessage(Integer.toHexString(length + 2));
63             String len2 = GoogleTVRequest.fixMessage(Integer.toHexString(length));
64             return "080210c801c202" + len1 + "0a" + len2 + pin;
65         }
66     }
67
68     public static String loginRequest(int messageId) {
69         return loginRequest(messageId, "");
70     }
71
72     public static String loginRequest(int messageId, String data) {
73         String message = "";
74         if (messageId == 1) {
75             // Send app and device name
76             // 080210c801522d 0a 19 636f6d2e676f6f676c652e616e64726f69642e766964656f73 12 10
77             // 73616d73756e6720534d2d4739393855
78             // ------------------LEN com.google.android.videos----------------------------LEN samsung SM-G998U
79             message = "080210c801522d0a19636f6d2e676f6f676c652e616e64726f69642e766964656f73121073616d73756e6720534d2d4739393855";
80         } else if (messageId == 2) {
81             // Unknown but required
82             // 080210c801a201 0e 0a 04 08031006 0a 04 08031004 1802
83             // ---------------LEN---LEN------------LEN
84             message = "080210c801a2010e0a04080310060a04080310041802";
85         } else if (messageId == 3) {
86             // Trigger PIN OSD
87             // ---------------LEN---LEN
88             // 080210c801a201 08 12 04 08031006 1801
89             // 080210c801f201 08 0a 04 08031006 1001
90             message = "080210c801f201080a04080310061001";
91         } else if (messageId == 4) {
92             // 0a 41 08 7e 12 3d 0a 08 534d2d4739393855 12 07 73616d73756e67 18 01 22 02 3133 2a
93             // ---LEN---------LEN---LEN--SM-G998U----------LEN--samsung---------
94             // 19 636f6d2e676f6f676c652e616e64726f69642e766964656f73 32
95             // LEN-com.google.android.videos----------------------------
96             // 07 342e33382e3138
97             // LEN-4.38.18
98             // message =
99             // "0a41087e123d0a08534d2d4739393855120773616d73756e671801220231332a19636f6d2e676f6f676c652e616e64726f69642e766964656f733207342e33382e3138";
100
101             // 0a 57 08 fe 04 12 52 0a 08 534d2d4739393855 12 07 73616d73756e67 18 01 22 02 3133 2a
102             // ---LEN------------LEN---LEN--SM-G998U----------LEN--samsung---------
103             // 19 636f6d2e676f6f676c652e616e64726f69642e766964656f73 32
104             // LEN-com.google.android.videos---------------------------
105             // 1c 342e33392e3538342e3532393538383538332e372d72656c65617365
106             // LEN-4.39.584.529588583.7-release
107             // message =
108             // "0a5708fe0412520a08534d2d4739393855120773616d73756e671801220231332a19636f6d2e676f6f676c652e616e64726f69642e766964656f73321c342e33392e3538342e3532393538383538332e372d72656c65617365";
109
110             // 0a 3b 08 ee 04 12 36 0a 06 6950686f6e65 12 05 4170706c65 18 02 22 04 31362e36 2a
111             // ---LEN------------LEN---LEN-iPhone---------LEN-Apple--------------LEN-16.6
112             // 11 636f6d2e676f6f676c652e4d6f76696573 32 0a 332e31332e3030303033
113             // LEN-com.google.Movies--------------------LEN-3.13.00003
114
115             // 0a 57 08 fe 04 12 52 0a 08 534d2d4739393855 12 07 73616d73756e67 18 01 22 02 3133 2a
116             // ---LEN------------LEN---LEN--SM-G998U----------LEN--samsung---------
117             // 19 636f6d2e676f-6f676c652e616e64726f69642e766964656f73 32
118             // LEN-com.google.android.videos---------------------------
119             // 1c 342e33392e3634342e3533343836353739392e332d72656c65617365
120             // LEN-4.39.644.534865799.3-release
121             int dataInt = Integer.parseInt(data, 16) - 1;
122             String updatedData = Integer.toHexString(dataInt);
123             message = "0a5708" + updatedData
124                     + "0412520a08534d2d4739393855120773616d73756e671801220231332a19636f6d2e676f6f676c652e616e64726f69642e766964656f73321c342e33392e3634342e3533343836353739392e332d72656c65617365";
125         } else if (messageId == 5) {
126             // Unknown. Sent after "1200" received
127             message = "1202087e";
128         }
129         return message;
130     }
131
132     public static String keepAlive(String request) {
133         // 42 07 08 01 10 e4f1 8d01
134         // 4a 02 08 01
135
136         // 42 08 08 7f 10 b4 908a a819
137         // 4a 02 08 7f
138
139         // 42 09 08 8001 10 ed b78a a819
140         // 4a 03 08 8001
141
142         char[] charArray = request.toCharArray();
143         StringBuilder sb = new StringBuilder();
144         sb.append(request);
145         sb.setLength(sb.toString().length() - 6);
146         String st = "";
147         do {
148             int sbLen = sb.toString().length();
149             st = "" + charArray[sbLen - 2] + charArray[sbLen - 1];
150             if (!DELIMITER_10.equals(st)) {
151                 sb.setLength(sbLen - 2);
152             }
153         } while (!DELIMITER_10.equals(st));
154         sb.setLength(sb.toString().length() - 2);
155
156         StringBuilder sbReply = new StringBuilder();
157         for (int i = 4; i < sb.toString().length(); i++) {
158             sbReply.append(charArray[i]);
159         }
160         return "4a" + fixMessage(Integer.toHexString(sbReply.toString().length() / 2)) + sbReply.toString();
161     }
162
163     public static String fixMessage(String tempMsg) {
164         if (tempMsg.length() % 2 > 0) {
165             tempMsg = "0" + tempMsg;
166         }
167         return tempMsg;
168     }
169 }