/**
* Copyright (c) 2010-2016 by the respective copyright holders.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.openhab.binding.souliss.internal.network.udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import org.openhab.binding.souliss.internal.network.typicals.SoulissNetworkParameter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This class provide to construct MaCaco and UDP frame
*
* @author Alessandro Del Pex
* @author Tonino Fazio
* @since 1.7.0
*/
public class SoulissCommGate {
private static Logger logger = LoggerFactory.getLogger(SoulissCommGate.class);
public static void sendFORCEFrame(DatagramSocket datagramSocket, String soulissNodeIPAddressOnLAN, int IDNode,
int slot, short shortCommand) {
sendFORCEFrame(datagramSocket, soulissNodeIPAddressOnLAN, IDNode, slot, shortCommand, null, null, null);
}
/*
* used for set dimmer value. It set command at first byte and dimmerVal to
* second byte
*/
public static void sendFORCEFrame(DatagramSocket datagramSocket, String soulissNodeIPAddressOnLAN, int IDNode,
int slot, short shortCommand, short lDimmer) {
sendFORCEFrame(datagramSocket, soulissNodeIPAddressOnLAN, IDNode, slot, shortCommand, lDimmer, null, null);
}
/*
* send force frame with command and RGB value
*/
public static void sendFORCEFrame(DatagramSocket datagramSocket, String soulissNodeIPAddressOnLAN, int IDNode,
int slot, short shortCommand, Short byte1, Short byte2, Short byte3) {
ArrayList<Byte> MACACOframe = new ArrayList<Byte>();
MACACOframe.add(ConstantsUDP.Souliss_UDP_function_force);
// PUTIN, STARTOFFEST, NUMBEROF
MACACOframe.add((byte) 0x0);// PUTIN
MACACOframe.add((byte) 0x0);// PUTIN
MACACOframe.add((byte) (IDNode));// Start Offset
if (byte1 == null && byte2 == null && byte3 == null) {
MACACOframe.add((byte) ((byte) slot + 1)); // Number Of
} else if (byte2 == null && byte3 == null) {
MACACOframe.add((byte) ((byte) slot + 2)); // Number Of byte of
// payload= command +
// set byte
} else {
MACACOframe.add((byte) ((byte) slot + 4)); // Number Of byte of
// payload= OnOFF + Red
// + Green + Blu
}
for (int i = 0; i <= slot - 1; i++) {
MACACOframe.add((byte) 00); // pongo a zero i byte precedenti lo
// slot da modificare
}
MACACOframe.add((byte) shortCommand);// PAYLOAD
if (byte1 != null && byte2 != null && byte3 != null) {
MACACOframe.add(byte1.byteValue());// PAYLOAD RED
MACACOframe.add(byte2.byteValue());// PAYLOAD GREEN
MACACOframe.add(byte3.byteValue());// PAYLOAD BLUE
} else if (byte1 != null) {
MACACOframe.add(byte1.byteValue());// PAYLOAD DIMMER
}
logger.debug("sendFORCEFrame - {}, soulissNodeIPAddressOnLAN: {}", MaCacoToString(MACACOframe),
soulissNodeIPAddressOnLAN);
send(datagramSocket, MACACOframe, soulissNodeIPAddressOnLAN);
}
/*
* T31 send force frame with command and setpoint float
*/
public static void sendFORCEFrameT31SetPoint(DatagramSocket datagramSocket, String soulissNodeIPAddressOnLAN,
int IDNode, int slot, short shortCommand, Short byte1, Short byte2) {
ArrayList<Byte> MACACOframe = new ArrayList<Byte>();
MACACOframe.add(ConstantsUDP.Souliss_UDP_function_force);
// PUTIN, STARTOFFEST, NUMBEROF
MACACOframe.add((byte) 0x0);// PUTIN
MACACOframe.add((byte) 0x0);// PUTIN
MACACOframe.add((byte) (IDNode));// Start Offset
MACACOframe.add((byte) ((byte) slot + 5)); // Number Of byte of payload= command + set byte
for (int i = 0; i <= slot - 1; i++) {
MACACOframe.add((byte) 00); // pongo a zero i byte precedenti lo
// slot da modificare
}
MACACOframe.add((byte) shortCommand);// PAYLOAD
MACACOframe.add((byte) 0x0);// Empty - Temperature Measured Value
MACACOframe.add((byte) 0x0);// Empty - Temperature Measured Value
MACACOframe.add(byte1.byteValue());// Temperature Setpoint Value
MACACOframe.add(byte2.byteValue());// Temperature Setpoint Value
logger.debug("sendFORCEFrame - {}, soulissNodeIPAddressOnLAN: {}", MaCacoToString(MACACOframe),
soulissNodeIPAddressOnLAN);
send(datagramSocket, MACACOframe, soulissNodeIPAddressOnLAN);
}
public static void sendDBStructFrame(DatagramSocket socket, String soulissNodeIPAddressOnLAN) {
ArrayList<Byte> MACACOframe = new ArrayList<Byte>();
MACACOframe.add((byte) ConstantsUDP.Souliss_UDP_function_db_struct);
MACACOframe.add((byte) 0x0);// PUTIN
MACACOframe.add((byte) 0x0);// PUTIN
MACACOframe.add((byte) 0x0);// Start Offset
MACACOframe.add((byte) 0x07); // Number Of
logger.debug("sendDBStructFrame - {}, soulissNodeIPAddressOnLAN: {}", MaCacoToString(MACACOframe),
soulissNodeIPAddressOnLAN);
send(socket, MACACOframe, soulissNodeIPAddressOnLAN);
// Note:
// Structure of DBStructFrame:
// nodes = mac.get(5);
// maxnodes = mac.get(6);
// maxTypicalXnode = mac.get(7);
// maxrequests = mac.get(8);
// MaCacoIN_s = mac.get(9);
// MaCacoTyp_s = mac.get(10);
// MaCacoOUT_s = mac.get(11);
}
/*
* send UDP frame
*/
private static void send(DatagramSocket socket, ArrayList<Byte> MACACOframe, String sSoulissNodeIPAddressOnLAN) {
int iUserIndex = SoulissNetworkParameter.UserIndex;
int iNodeIndex = SoulissNetworkParameter.NodeIndex;
;
ArrayList<Byte> buf = buildVNetFrame(MACACOframe, sSoulissNodeIPAddressOnLAN, iUserIndex, iNodeIndex);
byte[] merd = toByteArray(buf);
InetAddress serverAddr;
try {
serverAddr = InetAddress.getByName(sSoulissNodeIPAddressOnLAN);
DatagramPacket packet = new DatagramPacket(merd, merd.length, serverAddr, ConstantsUDP.SOULISSPORT);
SendDispatcher.put(socket, packet);
} catch (IOException e) {
e.printStackTrace();
logger.error(e.getMessage());
}
}
/*
* Build VNet Frame
*/
private static ArrayList<Byte> buildVNetFrame(ArrayList<Byte> MACACOframe2, String soulissNodeIPAddress,
int iUserIndex, int iNodeIndex) {
ArrayList<Byte> frame = new ArrayList<Byte>();
InetAddress ip;
try {
ip = InetAddress.getByName(soulissNodeIPAddress);
} catch (UnknownHostException e) {
e.printStackTrace();
return frame;
}
byte[] dude = ip.getAddress();
frame.add((byte) 23);// PUTIN
frame.add(dude[3]);// es 192.168.1.XX BOARD
// n broadcast : La comunicazione avviene utilizzando l'indirizzo IP
// 255.255.255.255 a cui associare l'indirizzo vNet 0xFFFF.
frame.add((byte) soulissNodeIPAddress.compareTo(ConstantsUDP.BROADCASTADDR) == 0 ? dude[2] : 0);
// 192.168.XX.0
frame.add((byte) iNodeIndex); // NODE INDEX
frame.add((byte) iUserIndex);// USER IDX
// aggiunge in testa il calcolo
frame.add(0, (byte) (frame.size() + MACACOframe2.size() + 1));
frame.add(0, (byte) (frame.size() + MACACOframe2.size() + 1));// Check 2
frame.addAll(MACACOframe2);
return frame;
}
/**
* Builds old-school byte array
*
* @param buf
* @return
*/
private static byte[] toByteArray(ArrayList<Byte> buf) {
byte[] merd = new byte[buf.size()];
for (int i = 0; i < buf.size(); i++) {
merd[i] = buf.get(i);
}
return merd;
}
/**
* Build MULTICAST FORCE Frame
*/
public static void sendMULTICASTFORCEFrame(DatagramSocket datagramSocket, String soulissNodeIPAddressOnLAN,
short typical, short shortCommand) {
ArrayList<Byte> MACACOframe = new ArrayList<Byte>();
MACACOframe.add(ConstantsUDP.Souliss_UDP_function_force_massive);
// PUTIN, STARTOFFEST, NUMBEROF
MACACOframe.add((byte) 0x0);// PUTIN
MACACOframe.add((byte) 0x0);// PUTIN
MACACOframe.add((byte) typical);// Start Offset
MACACOframe.add((byte) 1); // Number Of
MACACOframe.add((byte) shortCommand);// PAYLOAD
logger.debug("sendMULTICASTFORCEFrame - {}, soulissNodeIPAddressOnLAN: {}", MaCacoToString(MACACOframe),
soulissNodeIPAddressOnLAN);
send(datagramSocket, MACACOframe, soulissNodeIPAddressOnLAN);
}
/**
* Build PING Frame
*/
public static void sendPing(DatagramSocket datagramSocket, String soulissNodeIPAddressOnLAN, short putIn_1,
short punIn_2) {
ArrayList<Byte> MACACOframe = new ArrayList<Byte>();
MACACOframe.add(ConstantsUDP.Souliss_UDP_function_ping);
// PUTIN, STARTOFFEST, NUMBEROF
MACACOframe.add((byte) putIn_1);// PUTIN
MACACOframe.add((byte) punIn_2);// PUTIN
MACACOframe.add((byte) 0x00);// Start Offset
MACACOframe.add((byte) 0x00); // Number Of
logger.debug("sendPing - {}, soulissNodeIPAddressOnLAN: {}", MaCacoToString(MACACOframe),
soulissNodeIPAddressOnLAN);
send(datagramSocket, MACACOframe, soulissNodeIPAddressOnLAN);
}
/**
* Build SUBSCRIPTION Frame
*/
public static void sendSUBSCRIPTIONframe(DatagramSocket datagramSocket, String soulissNodeIPAddressOnLAN,
int iNodes) {
ArrayList<Byte> MACACOframe = new ArrayList<Byte>();
MACACOframe.add(ConstantsUDP.Souliss_UDP_function_subscribe);
// PUTIN, STARTOFFEST, NUMBEROF
MACACOframe.add((byte) 0x00);// PUTIN
MACACOframe.add((byte) 0x00);// PUTIN
MACACOframe.add((byte) 0x00);
MACACOframe.add((byte) iNodes); // Start Offset (is the first node to
// consider
logger.debug("sendSUBSCRIPTIONframe - {}, soulissNodeIPAddressOnLAN: {}", MaCacoToString(MACACOframe),
soulissNodeIPAddressOnLAN);
send(datagramSocket, MACACOframe, soulissNodeIPAddressOnLAN);
}
/**
* Build HEALTY REQUEST Frame
*/
public static void sendHEALTY_REQUESTframe(DatagramSocket datagramSocket, String soulissNodeIPAddressOnLAN,
int iNodes) {
ArrayList<Byte> MACACOframe = new ArrayList<Byte>();
MACACOframe.add(ConstantsUDP.Souliss_UDP_function_healthReq);
// PUTIN, STARTOFFEST, NUMBEROF
MACACOframe.add((byte) 0x00);// PUTIN
MACACOframe.add((byte) 0x00);// PUTIN
MACACOframe.add((byte) 0x00);
MACACOframe.add((byte) iNodes);
logger.debug("sendHEALTY_REQUESTframe - {}, soulissNodeIPAddressOnLAN: {}", MaCacoToString(MACACOframe),
soulissNodeIPAddressOnLAN);
send(datagramSocket, MACACOframe, soulissNodeIPAddressOnLAN);
}
/**
* Build TYPICAL REQUEST Frame
*/
public static void sendTYPICAL_REQUESTframe(DatagramSocket datagramSocket, String soulissNodeIPAddressOnLAN,
int iNodes) {
ArrayList<Byte> MACACOframe = new ArrayList<Byte>();
MACACOframe.add(ConstantsUDP.Souliss_UDP_function_typreq);
// PUTIN, STARTOFFEST, NUMBEROF
MACACOframe.add((byte) 0x00);// PUTIN
MACACOframe.add((byte) 0x00);// PUTIN
MACACOframe.add((byte) 0x00); // startOffset
MACACOframe.add((byte) iNodes);
logger.debug("sendHEALTY_REQUESTframe - {}, soulissNodeIPAddressOnLAN: {}", MaCacoToString(MACACOframe),
soulissNodeIPAddressOnLAN);
send(datagramSocket, MACACOframe, soulissNodeIPAddressOnLAN);
}
static boolean flag = true;
private static String MaCacoToString(ArrayList<Byte> mACACOframe) {
while (!flag) {
}
;
// copio array per evitare modifiche concorrenti
ArrayList<Byte> mACACOframe2 = new ArrayList<Byte>();
mACACOframe2.addAll(mACACOframe);
flag = false;
StringBuilder sb = new StringBuilder();
sb.append("HEX: [");
for (byte b : mACACOframe2) {
sb.append(String.format("%02X ", b));
}
sb.append("]");
flag = true;
return sb.toString();
}
}