Skip to content

Commit 2e6cd2f

Browse files
committed
Implement Broadlink devices discovery
1 parent d266a92 commit 2e6cd2f

2 files changed

Lines changed: 149 additions & 3 deletions

File tree

‎src/main/java/com/github/mob41/blapi/BLDevice.java‎

Lines changed: 148 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,29 @@
2323
*******************************************************************************/
2424
package com.github.mob41.blapi;
2525

26+
import java.io.IOException;
27+
import java.net.DatagramPacket;
28+
import java.net.DatagramSocket;
29+
import java.net.InetAddress;
30+
import java.net.SocketTimeoutException;
31+
import java.util.ArrayList;
32+
import java.util.List;
33+
34+
import org.slf4j.Logger;
35+
import org.slf4j.LoggerFactory;
36+
37+
import com.github.mob41.blapi.mac.Mac;
38+
import com.github.mob41.blapi.pkt.DiscoveryPacket;
39+
2640
/**
2741
* This is the base class of all Broadlink devices (e.g. SP1, RMPro)
2842
* @author Anthony
2943
*
3044
*/
3145
public abstract class BLDevice {
3246

47+
private static final Logger log = LoggerFactory.getLogger(BLDevice.class);
48+
3349
public static final byte[] INITIAL_KEY = {
3450
0x09, 0x76, 0x28, 0x34,
3551
0x3f, (byte) 0xe9, (byte) 0x9e, 0x23,
@@ -89,9 +105,139 @@ public abstract class BLDevice {
89105
public static final short DEV_A1 = 0x2714;
90106

91107
public static final short DEV_MP1 = 0x4EB5;
108+
109+
public static final int DISCOVERY_DEST_PORT = 80;
110+
111+
public static final int DISCOVERY_RECEIVE_BUFFER_SIZE = 0x40; //64-bytes
92112

93-
public BLDevice(short deviceType, String host, String mac) {
113+
protected BLDevice(short deviceType, String host, Mac mac) {
94114

95115
}
96-
116+
117+
public static BLDevice createInstance(short deviceType, String host, Mac mac){
118+
switch (deviceType){
119+
case DEV_RM_2:
120+
}
121+
return null;
122+
}
123+
124+
public static BLDevice[] discoverDevices(InetAddress sourceIpAddr, int sourcePort, int timeout) throws IOException{
125+
List<BLDevice> devices = new ArrayList<BLDevice>(50);
126+
127+
DiscoveryPacket dpkt = new DiscoveryPacket(sourceIpAddr, sourcePort);
128+
129+
DatagramSocket sock = new DatagramSocket(sourcePort, sourceIpAddr);
130+
sock.setBroadcast(true);
131+
sock.setReuseAddress(true);
132+
133+
byte[] sendBytes = dpkt.getData();
134+
DatagramPacket sendpack = new DatagramPacket(sendBytes, sendBytes.length,
135+
InetAddress.getByName("255.255.255.255"), DISCOVERY_DEST_PORT);
136+
sock.send(sendpack);
137+
138+
byte[] receBytes = new byte[DISCOVERY_RECEIVE_BUFFER_SIZE];
139+
140+
DatagramPacket recePacket = new DatagramPacket(receBytes, 0, receBytes.length);
141+
if (timeout == 0){
142+
sock.receive(recePacket);
143+
sock.close();
144+
145+
String host = recePacket.getAddress().getHostAddress();
146+
Mac mac = new Mac(subbytes(receBytes, 0x3a, 0x40));
147+
short deviceType = (short) (receBytes[0x34] | receBytes[0x35] << 8);
148+
149+
BLDevice inst = createInstance(deviceType, host, mac);
150+
151+
if (inst != null){
152+
devices.add(inst);
153+
}
154+
} else {
155+
long startTime = System.currentTimeMillis();
156+
long elapsed;
157+
while ((elapsed = System.currentTimeMillis() - startTime) < timeout){
158+
sock.setSoTimeout((int) (timeout - elapsed));
159+
160+
try {
161+
sock.receive(recePacket);
162+
} catch (SocketTimeoutException e){
163+
break;
164+
}
165+
166+
String host = recePacket.getAddress().getHostAddress();
167+
Mac mac = new Mac(subbytes(receBytes, 0x3a, 0x40));
168+
short deviceType = (short) (receBytes[0x34] | receBytes[0x35] << 8);
169+
170+
BLDevice inst = createInstance(deviceType, host, mac);
171+
172+
if (inst != null){
173+
devices.add(inst);
174+
}
175+
}
176+
}
177+
178+
BLDevice[] out = new BLDevice[devices.size()];
179+
for (int i = 0; i < out.length; i++){
180+
out[i] = devices.get(i);
181+
}
182+
183+
return out;
184+
}
185+
186+
/**
187+
* Picks bytes from start-set to the end-set in a bytes array
188+
* @param data The bytes array to be used
189+
* @param start The starting position to be picked
190+
* @param end The ending position to be picked
191+
* @return The bytes array picked with length (<code>end - start</code>)
192+
*/
193+
public static byte[] subbytes(byte[] data, int start, int end){
194+
byte[] out = new byte[end - start];
195+
196+
int outi = 0;
197+
for (int i = start; i < end; i += 0x01, outi++){
198+
out[outi] = data[i];
199+
}
200+
201+
return out;
202+
}
203+
204+
/* Not this! This will only send once and close the connection
205+
/**
206+
* Sends a compiled packet to a destination host and port, and
207+
* receives a datagram from the source port specified.
208+
* @param pkt The compiled packet to be sent
209+
* @param sourceIpAddr Source IP address to be binded for receiving datagrams
210+
* @param sourcePort Source Port to be bineded for receiving datagrams
211+
* @param destIpAddr Destination IP address
212+
* @param destPort Destination Port
213+
* @param timeout Socket timeout. 0 will disable the timeout
214+
* @param bufSize Receiving datagram's buffer size
215+
* @return The received datagram
216+
* @throws IOException Thrown if socket timed out, cannot bind source IP and source port, no permission, etc.
217+
*\/
218+
public static DatagramPacket sendPkt(Packet pkt,
219+
InetAddress sourceIpAddr, int sourcePort,
220+
InetAddress destIpAddr, int destPort,
221+
int timeout, int bufSize) throws IOException{
222+
DatagramSocket sock = new DatagramSocket(sourcePort, sourceIpAddr);
223+
sock.setBroadcast(true);
224+
sock.setReuseAddress(true);
225+
226+
//sock.bind(new InetSocketAddress(ipAddr, sourcePort));
227+
228+
byte[] data = pkt.getData();
229+
DatagramPacket sendpack = new DatagramPacket(data, data.length, destIpAddr, destPort);
230+
sock.send(sendpack);
231+
232+
byte[] rece = new byte[bufSize];
233+
234+
DatagramPacket recepack = new DatagramPacket(rece, 0, rece.length);
235+
sock.setSoTimeout(timeout);
236+
sock.receive(recepack);
237+
238+
sock.close();
239+
240+
return recepack;
241+
}
242+
*/
97243
}

‎src/main/java/com/github/mob41/blapi/pkt/DiscoveryPacket.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public DiscoveryPacket(InetAddress localIpAddr, int sourcePort, Calendar cal, Ti
6969
int year = cal.get(Calendar.YEAR);
7070
int dayOfWk = dayOfWeekConv(cal.get(Calendar.DAY_OF_WEEK)); //Day of week (May return -1 if Calendar return a wrong field value)
7171
int dayOfMn = cal.get(Calendar.DAY_OF_MONTH); //Day of month
72-
int month = cal.get(Calendar.MONTH); //Month
72+
int month = cal.get(Calendar.MONTH + 1); //Month
7373

7474
if (debug){
7575
log.debug("min=" + min + " hr=" + hr);

0 commit comments

Comments
 (0)