com.zsmartsystems.zigbee.dongle.ember.autocode.CommandGenerator Maven / Gradle / Ivy
/**
* Copyright (c) 2016-2024 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 com.zsmartsystems.zigbee.dongle.ember.autocode;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import com.zsmartsystems.zigbee.dongle.ember.autocode.xml.Command;
import com.zsmartsystems.zigbee.dongle.ember.autocode.xml.Enumeration;
import com.zsmartsystems.zigbee.dongle.ember.autocode.xml.Parameter;
import com.zsmartsystems.zigbee.dongle.ember.autocode.xml.Protocol;
import com.zsmartsystems.zigbee.dongle.ember.autocode.xml.Structure;
import com.zsmartsystems.zigbee.dongle.ember.autocode.xml.Value;
/**
*
* @author Chris Jackson
*
*/
public class CommandGenerator extends ClassGenerator {
protected final String ashPackage = "com.zsmartsystems.zigbee.dongle.ember.internal.ash";
protected final String ezspPackage = "com.zsmartsystems.zigbee.dongle.ember.ezsp";
protected final String serializerPackage = "com.zsmartsystems.zigbee.dongle.ember.internal.serializer";
protected final String ezspCommandPackage = "com.zsmartsystems.zigbee.dongle.ember.ezsp.command";
protected final String ezspStructurePackage = "com.zsmartsystems.zigbee.dongle.ember.ezsp.structure";
public void go(Protocol protocol) throws FileNotFoundException, UnsupportedEncodingException {
String className;
for (Command command : protocol.commands) {
if (command.name.endsWith("Handler")) {
className = "Ezsp" + command.name.substring(0, 1).toUpperCase() + command.name.substring(1);
createCommandClass(className, command, command.response_parameters);
} else {
className = "Ezsp" + upperCaseFirstCharacter(command.name) + "Request";
createCommandClass(className, command, command.command_parameters);
className = "Ezsp" + command.name.substring(0, 1).toUpperCase() + command.name.substring(1)
+ "Response";
createCommandClass(className, command, command.response_parameters);
}
}
createEmberFrame(protocol);
for (Structure structure : protocol.structures) {
createStructureClass(structure);
}
for (Enumeration enumeration : protocol.enumerations) {
createEnumClass(enumeration);
}
}
private void createCommandClass(String className, Command command, List parameters)
throws FileNotFoundException, UnsupportedEncodingException {
System.out.println("Processing command class " + command.name + " [" + className + "()]");
OutputStream stringWriter = new ByteArrayOutputStream();
PrintStream out = new PrintStream(stringWriter, false, "UTF-8");
clearImports();
// addImport("org.slf4j.Logger");
// addImport("org.slf4j.LoggerFactory");
// addImport("java.util.Map");
// addImport("java.util.HashMap");
out.println("/**");
out.println(" * Class to implement the Ember EZSP command " + command.name + ".");
out.println(" * ");
outputWithLinebreak(out, "", command.description);
out.println(" *
");
out.println(" * This class provides methods for processing EZSP commands.");
out.println(" *
");
out.println(" * Note that this code is autogenerated. Manual changes may be overwritten.");
out.println(" *");
out.println(" * @author Chris Jackson - Initial contribution of Java code generator");
out.println(" */");
if (className.endsWith("Request")) {
addImport(ezspPackage + ".EzspFrameRequest");
out.println("public class " + className + " extends EzspFrameRequest {");
} else {
addImport(ezspPackage + ".EzspFrameResponse");
out.println("public class " + className + " extends EzspFrameResponse {");
}
out.println(" public static final int FRAME_ID = " + String.format("0x%02X", command.id) + ";");
// out.println(" private static final Logger logger = LoggerFactory.getLogger(" + className + ".class);");
for (Parameter parameter : parameters) {
if (parameter.auto_size != null) {
continue;
}
out.println();
out.println(" /**");
if (parameter.description.length() != 0) {
outputWithLinebreak(out, " ", parameter.description);
out.println(" *
");
}
out.println(" * EZSP type is " + parameter.data_type + " - Java type is {@link "
+ getTypeClass(parameter.data_type) + "}");
out.println(" */");
out.println(" private " + getTypeClass(parameter.data_type) + " " + parameter.name + ";");
}
if (className.endsWith("Request")) {
addImport(serializerPackage + ".EzspSerializer");
out.println();
out.println(" /**");
out.println(" * Serialiser used to serialise to binary line data");
out.println(" */");
out.println(" private EzspSerializer serializer;");
out.println();
out.println(" /**");
out.println(" * Request constructor");
out.println(" */");
out.println(" public " + className + "() {");
out.println(" frameId = FRAME_ID;");
out.println(" serializer = new EzspSerializer();");
out.println(" }");
} else {
out.println();
out.println(" /**");
out.println(" * Response and Handler constructor");
out.println(" */");
out.println(" public " + className + "(int[] inputBuffer) {");
out.println(" // Super creates deserializer and reads header fields");
out.println(" super(inputBuffer);");
out.println();
out.println(" // Deserialize the fields");
Map autoSizers = new HashMap();
for (Parameter parameter : parameters) {
if (parameter.auto_size != null) {
out.println(" int " + parameter.name + " = deserializer.deserialize"
+ getTypeSerializer(parameter.data_type) + "();");
autoSizers.put(parameter.auto_size, parameter.name);
continue;
}
if (autoSizers.get(parameter.name) != null) {
out.println(" " + parameter.name + "= deserializer.deserialize"
+ getTypeSerializer(parameter.data_type) + "(" + autoSizers.get(parameter.name) + ");");
continue;
}
if (parameter.data_type.contains("[") && parameter.data_type.contains("]")
&& !parameter.data_type.contains("[]")) {
int length = Integer.parseInt(parameter.data_type.substring(parameter.data_type.indexOf("[") + 1,
parameter.data_type.indexOf("]")));
out.println(" " + parameter.name + " = deserializer.deserialize"
+ getTypeSerializer(parameter.data_type) + "(" + length + ");");
continue;
}
out.println(" " + parameter.name + " = deserializer.deserialize"
+ getTypeSerializer(parameter.data_type) + "();");
}
out.println(" }");
}
for (Parameter parameter : parameters) {
if (parameter.auto_size != null) {
continue;
}
out.println();
out.println(" /**");
if (parameter.description.length() != 0) {
outputWithLinebreak(out, " ", parameter.description);
out.println(" * ");
}
out.println(" * EZSP type is " + parameter.data_type + " - Java type is {@link "
+ getTypeClass(parameter.data_type) + "}");
out.println(" *");
out.println(" * @return the current " + parameter.name + " as {@link "
+ getTypeClass(parameter.data_type) + "}");
out.println(" */");
out.println(" public " + getTypeClass(parameter.data_type) + " get"
+ upperCaseFirstCharacter(parameter.name) + "() {");
out.println(" return " + parameter.name + ";");
out.println(" }");
out.println();
out.println(" /**");
if (parameter.description.length() != 0) {
outputWithLinebreak(out, " ", parameter.description);
}
out.println(" *");
out.println(" * @param " + parameter.name + " the " + parameter.name + " to set as {@link "
+ getTypeClass(parameter.data_type) + "}");
out.println(" */");
out.println(" public void set" + upperCaseFirstCharacter(parameter.name) + "("
+ getTypeClass(parameter.data_type) + " " + parameter.name + ") {");
out.println(" this." + parameter.name + " = " + parameter.name + ";");
out.println(" }");
}
if (className.endsWith("Request")) {
out.println();
out.println(" @Override");
out.println(" public int[] serialize() {");
out.println(" // Serialize the header");
out.println(" serializeHeader(serializer);");
out.println();
out.println(" // Serialize the fields");
for (Parameter parameter : parameters) {
if (parameter.auto_size != null) {
out.println(" serializer.serialize" + getTypeSerializer(parameter.data_type) + "("
+ parameter.auto_size + ".length);");
continue;
}
out.println(" serializer.serialize" + getTypeSerializer(parameter.data_type) + "("
+ parameter.name + ");");
}
out.println(" return serializer.getPayload();");
out.println(" }");
} else {
}
out.println();
out.println(" @Override");
out.println(" public String toString() {");
out.println(" final StringBuilder builder = new StringBuilder("
+ (className.length() + 3 + (parameters.size() + 1) * 25) + ");");
out.println(" builder.append(\"" + className + " [networkId=\");");
out.println(" builder.append(networkId);");
for (Parameter parameter : parameters) {
if (parameter.auto_size != null) {
continue;
}
out.println(" builder.append(\", " + parameter.name + "=\");");
if (parameter.data_type.contains("[")) {
out.println(" for (int cnt = 0; cnt < " + parameter.name + ".length; cnt++) {");
out.println(" if (cnt > 0) {");
out.println(" builder.append(' ');");
out.println(" }");
out.println(" builder.append(" + formatParameterString(parameter) + ");");
out.println(" }");
} else {
out.println(" builder.append(" + formatParameterString(parameter) + ");");
}
}
out.println(" builder.append(']');");
out.println(" return builder.toString();");
out.println(" }");
out.println("}");
out.flush();
File packageFile = new File(sourceRootPath + ezspCommandPackage.replace(".", "/"));
PrintStream outFile = getClassOut(packageFile, className);
outputCopywrite(outFile);
outFile.println("package " + ezspCommandPackage + ";");
outFile.println();
outputImports(outFile);
outFile.println();
outFile.print(stringWriter.toString());
outFile.flush();
outFile.close();
out.close();
}
private void createStructureClass(Structure structure) throws FileNotFoundException, UnsupportedEncodingException {
String className = upperCaseFirstCharacter(structure.name);
System.out.println("Processing structure class " + structure.name + " [" + className + "()]");
OutputStream stringWriter = new ByteArrayOutputStream();
PrintStream out = new PrintStream(stringWriter, false, "UTF-8");
clearImports();
// addImport("org.slf4j.Logger");
// addImport("org.slf4j.LoggerFactory");
// addImport("java.util.Map");
// addImport("java.util.HashMap");
addImport(serializerPackage + ".EzspSerializer");
addImport(serializerPackage + ".EzspDeserializer");
out.println("/**");
out.println(" * Class to implement the Ember Structure " + structure.name + ".");
out.println(" *
");
if (structure.description.length() != 0) {
outputWithLinebreak(out, "", structure.description);
out.println(" *
");
}
out.println(" * Note that this code is autogenerated. Manual changes may be overwritten.");
out.println(" *");
out.println(" * @author Chris Jackson - Initial contribution of Java code generator");
out.println(" */");
out.println("public class " + className + " {");
for (Parameter parameter : structure.parameters) {
if (parameter.auto_size != null) {
continue;
}
out.println();
out.println(" /**");
if (parameter.description.length() != 0) {
outputWithLinebreak(out, " ", parameter.description);
out.println(" *
");
}
out.println(" * EZSP type is " + parameter.data_type + " - Java type is {@link "
+ getTypeClass(parameter.data_type) + "}");
if (parameter.multiple) {
out.println(" * Parameter allows multiple options so implemented as a {@link Set}.");
}
out.println(" */");
if (parameter.multiple) {
addImport("java.util.Set");
addImport("java.util.HashSet");
out.println(" private Set<" + getTypeClass(parameter.data_type) + "> " + parameter.name
+ " = new HashSet<" + getTypeClass(parameter.data_type) + ">();");
} else {
out.println(" private " + getTypeClass(parameter.data_type) + " " + parameter.name + ";");
}
}
out.println();
out.println(" /**");
out.println(" * Default Constructor");
out.println(" */");
out.println(" public " + className + "() {");
out.println(" }");
out.println();
out.println(" public " + className + "(EzspDeserializer deserializer) {");
out.println(" deserialize(deserializer);");
out.println(" }");
for (Parameter parameter : structure.parameters) {
if (parameter.auto_size != null) {
continue;
}
out.println();
out.println(" /**");
if (parameter.description.length() != 0) {
outputWithLinebreak(out, " ", parameter.description);
out.println(" *
");
}
out.println(" * EZSP type is " + parameter.data_type + " - Java type is {@link "
+ getTypeClass(parameter.data_type) + "}");
out.println(" *");
if (parameter.multiple) {
out.println(" * @return the current " + parameter.name + " as {@link Set} of {@link "
+ getTypeClass(parameter.data_type) + "}");
} else {
out.println(" * @return the current " + parameter.name + " as {@link "
+ getTypeClass(parameter.data_type) + "}");
}
out.println(" */");
if (parameter.multiple) {
out.println(" public Set<" + getTypeClass(parameter.data_type) + "> get"
+ upperCaseFirstCharacter(parameter.name) + "() {");
} else {
out.println(" public " + getTypeClass(parameter.data_type) + " get"
+ upperCaseFirstCharacter(parameter.name) + "() {");
}
out.println(" return " + parameter.name + ";");
out.println(" }");
out.println();
if (parameter.multiple) {
out.println(" /**");
if (parameter.description.length() != 0) {
outputWithLinebreak(out, " ", parameter.description);
}
out.println(" *");
out.println(" * @param " + parameter.name + " the " + parameter.name
+ " to add to the {@link Set} as {@link " + getTypeClass(parameter.data_type) + "}");
out.println(" */");
out.println(" public void add" + upperCaseFirstCharacter(parameter.name) + "("
+ getTypeClass(parameter.data_type) + " " + parameter.name + ") {");
out.println(" this." + parameter.name + ".add(" + parameter.name + ");");
out.println(" }");
out.println();
out.println(" /**");
if (parameter.description.length() != 0) {
outputWithLinebreak(out, " ", parameter.description);
}
out.println(" *");
out.println(" * @param " + parameter.name + " the " + parameter.name
+ " to remove to the {@link Set} as {@link " + getTypeClass(parameter.data_type) + "}");
out.println(" */");
out.println(" public void remove" + upperCaseFirstCharacter(parameter.name) + "("
+ getTypeClass(parameter.data_type) + " " + parameter.name + ") {");
out.println(" this." + parameter.name + ".remove(" + parameter.name + ");");
out.println(" }");
} else {
out.println(" /**");
if (parameter.description.length() != 0) {
outputWithLinebreak(out, " ", parameter.description);
}
out.println(" *");
out.println(" * @param " + parameter.name + " the " + parameter.name + " to set as {@link "
+ getTypeClass(parameter.data_type) + "}");
out.println(" */");
out.println(" public void set" + upperCaseFirstCharacter(parameter.name) + "("
+ getTypeClass(parameter.data_type) + " " + parameter.name + ") {");
out.println(" this." + parameter.name + " = " + parameter.name + ";");
out.println(" }");
}
}
out.println();
out.println(" /**");
out.println(" * Serialise the contents of the EZSP structure.");
out.println(" *");
out.println(" * @param serializer the {@link EzspSerializer} used to serialize");
out.println(" */");
out.println(" public int[] serialize(EzspSerializer serializer) {");
out.println(" // Serialize the fields");
for (Parameter parameter : structure.parameters) {
if (parameter.auto_size != null) {
out.println(" serializer.serialize" + getTypeSerializer(parameter.data_type) + "("
+ parameter.auto_size + ".length);");
out.println(" serializer.serialize" + getTypeSerializer(parameter.data_type) + "("
+ parameter.auto_size + ".length);");
continue;
}
out.println(" serializer.serialize" + getTypeSerializer(parameter.data_type) + "(" + parameter.name
+ ");");
}
out.println(" return serializer.getPayload();");
out.println(" }");
out.println();
out.println(" /**");
out.println(" * Deserialise the contents of the EZSP structure.");
out.println(" *");
out.println(" * @param deserializer the {@link EzspDeserializer} used to deserialize");
out.println(" */");
out.println(" public void deserialize(EzspDeserializer deserializer) {");
out.println(" // Deserialize the fields");
Map autoSizers = new HashMap();
for (Parameter parameter : structure.parameters) {
if (parameter.auto_size != null) {
out.println(" int " + parameter.name + " = deserializer.deserialize"
+ getTypeSerializer(parameter.data_type) + "();");
autoSizers.put(parameter.auto_size, parameter.name);
continue;
}
if (autoSizers.get(parameter.name) != null) {
out.println(" " + parameter.name + "= deserializer.deserialize"
+ getTypeSerializer(parameter.data_type) + "(" + autoSizers.get(parameter.name) + ");");
continue;
}
if (parameter.data_type.contains("[") && parameter.data_type.contains("]")
&& !parameter.data_type.contains("[]")) {
int length = Integer.parseInt(parameter.data_type.substring(parameter.data_type.indexOf("[") + 1,
parameter.data_type.indexOf("]")));
out.println(" " + parameter.name + " = deserializer.deserialize"
+ getTypeSerializer(parameter.data_type) + "(" + length + ");");
continue;
}
out.println(" " + parameter.name + " = deserializer.deserialize"
+ getTypeSerializer(parameter.data_type) + "();");
}
out.println(" }");
out.println();
out.println(" @Override");
out.println(" public String toString() {");
out.println(" final StringBuilder builder = new StringBuilder("
+ (className.length() + 3 + structure.parameters.size() * 25) + ");");
boolean first = true;
for (Parameter parameter : structure.parameters) {
if (parameter.auto_size != null) {
continue;
}
if (first) {
out.println(" builder.append(\"" + className + " [" + parameter.name + "=\");");
} else {
out.println(" builder.append(\", " + parameter.name + "=\");");
}
first = false;
// If it's an array, then we want to print hex data
if (parameter.data_type.contains("[")) {
out.println(" builder.append('{');");
out.println(" if (" + parameter.name + " == null) {");
out.println(" builder.append(\"null\");");
out.println(" } else {");
out.println(" for (int cnt = 0; cnt < " + parameter.name + ".length; cnt++) {");
out.println(" if (cnt != 0) {");
out.println(" builder.append(' ');");
out.println(" }");
// if(formatParameterString(parameter)==)
out.println(" builder.append(" + formatParameterString(parameter) + ");");
out.println(" }");
out.println(" }");
out.println(" builder.append('}');");
} else {
out.println(" builder.append(" + formatParameterString(parameter) + ");");
}
}
out.println(" builder.append(']');");
out.println(" return builder.toString();");
out.println(" }");
out.println("}");
out.flush();
File packageFile = new File(sourceRootPath + ezspStructurePackage.replace(".", "/"));
PrintStream outFile = getClassOut(packageFile, className);
outputCopywrite(outFile);
outFile.println("package " + ezspStructurePackage + ";");
outFile.println();
outputImports(outFile);
outFile.println();
outFile.print(stringWriter.toString());
outFile.flush();
outFile.close();
out.close();
}
private void createEnumClass(Enumeration enumeration) throws FileNotFoundException, UnsupportedEncodingException {
String className = upperCaseFirstCharacter(enumeration.name);
System.out.println("Processing enum class " + enumeration.name + " [" + className + "()]");
OutputStream stringWriter = new ByteArrayOutputStream();
PrintStream out = new PrintStream(stringWriter, false, "UTF-8");
clearImports();
addImport("java.util.Map");
addImport("java.util.HashMap");
out.println("/**");
out.println(" * Class to implement the Ember Enumeration " + enumeration.name + ".");
if (enumeration.description != null && enumeration.description.trim().length() > 0) {
out.println(" * ");
outputWithLinebreak(out, "", enumeration.description);
}
out.println(" *
");
out.println(" * Note that this code is autogenerated. Manual changes may be overwritten.");
out.println(" *");
out.println(" * @author Chris Jackson - Initial contribution of Java code generator");
out.println(" */");
out.println("public enum " + className + " {");
out.println(" /**");
out.println(" * Default unknown value");
out.println(" */");
out.println(" UNKNOWN(-1),");
boolean first = true;
for (Value value : enumeration.values) {
if (!first) {
out.println(",");
}
first = false;
out.println();
out.println(" /**");
if (value.description.length() != 0) {
outputWithLinebreak(out, " ", value.description);
}
out.println(" */");
out.print(" " + value.name + "(0x" + String.format("%04X", value.enum_value) + ")");
}
out.println(";");
out.println();
out.println(" /**");
out.println(" * A mapping between the integer code and its corresponding type to");
out.println(" * facilitate lookup by code.");
out.println(" */");
out.println(" private static Map codeMapping;");
out.println();
out.println(" private int key;");
out.println();
out.println(" static {");
out.println(" codeMapping = new HashMap();");
out.println(" for (" + className + " s : values()) {");
out.println(" codeMapping.put(s.key, s);");
out.println(" }");
out.println(" }");
out.println();
out.println(" private " + className + "(int key) {");
out.println(" this.key = key;");
out.println(" }");
out.println();
out.println(" /**");
out.println(" * Lookup function based on the EmberStatus type code. Returns null if the");
out.println(" * code does not exist.");
out.println(" *");
out.println(" * @param code the code to lookup");
out.println(" * @return enumeration value of the alarm type.");
out.println(" */");
out.println(" public static " + className + " get" + className + "(int code) {");
out.println(" if (codeMapping.get(code) == null) {");
out.println(" return UNKNOWN;");
out.println(" }");
out.println();
out.println(" return codeMapping.get(code);");
out.println(" }");
out.println();
out.println(" /**");
out.println(" * Returns the EZSP protocol defined value for this enumeration.");
out.println(" *");
out.println(" * @return the EZSP protocol key");
out.println(" */");
out.println(" public int getKey() {");
out.println(" return key;");
out.println(" }");
out.println("}");
out.flush();
File packageFile = new File(sourceRootPath + ezspStructurePackage.replace(".", "/"));
PrintStream outFile = getClassOut(packageFile, className);
outputCopywrite(outFile);
outFile.println("package " + ezspStructurePackage + ";");
outFile.println();
outputImports(outFile);
outFile.println();
outFile.print(stringWriter.toString());
outFile.flush();
outFile.close();
out.close();
}
protected String getTypeClass(String dataType) {
String modifier = "";
String dataTypeLocal = new String(dataType);
if (dataType.contains("[")) {
dataTypeLocal = dataTypeLocal.substring(0, dataTypeLocal.indexOf("["));
modifier = "[]";
}
switch (dataTypeLocal) {
case "bool":
return "boolean";
case "EmberNodeId":
case "EmberCounterType":
case "EmberGpSecurityFrameCounter":
case "EzspDecisionBitmask":
case "EmberMulticastId":
case "int8s":
case "uint8_u":
case "uint8_t":
case "uint16_t":
case "uint32_t":
return "int" + modifier;
// }
// int size = Integer.parseInt(dataType.substring(dataType.indexOf("[") + 1, dataType.indexOf("]")));
// return "int[" + size + "]";
case "ExtendedPanId":
addImport("com.zsmartsystems.zigbee.ExtendedPanId");
return "ExtendedPanId";
case "EmberEUI64":
addImport("com.zsmartsystems.zigbee.IeeeAddress");
return "IeeeAddress";
case "EmberRouteTableEntry":
addImport(ezspStructurePackage + ".EmberRouteTableEntry");
return "EmberRouteTableEntry";
case "EmberBindingTableEntry":
addImport(ezspStructurePackage + ".EmberBindingTableEntry");
return "EmberBindingTableEntry";
case "EmberZigbeeNetwork":
addImport(ezspStructurePackage + ".EmberZigbeeNetwork");
return "EmberZigbeeNetwork";
case "EmberNeighborTableEntry":
addImport(ezspStructurePackage + ".EmberNeighborTableEntry");
return "EmberNeighborTableEntry";
case "EmberInitialSecurityState":
addImport(ezspStructurePackage + ".EmberInitialSecurityState");
return "EmberInitialSecurityState";
case "EmberCurrentSecurityState":
addImport(ezspStructurePackage + ".EmberCurrentSecurityState");
return "EmberCurrentSecurityState";
case "EmberOutgoingMessageType":
addImport(ezspStructurePackage + ".EmberOutgoingMessageType");
return "EmberOutgoingMessageType";
case "EzspDecisionId":
addImport(ezspStructurePackage + ".EzspDecisionId");
return "EzspDecisionId";
case "EmberIncomingMessageType":
addImport(ezspStructurePackage + ".EmberIncomingMessageType");
return "EmberIncomingMessageType";
case "EmberApsFrame":
addImport(ezspStructurePackage + ".EmberApsFrame");
return "EmberApsFrame";
case "EzspPolicyId":
addImport(ezspStructurePackage + ".EzspPolicyId");
return "EzspPolicyId";
case "EzspNetworkScanType":
addImport(ezspStructurePackage + ".EzspNetworkScanType");
return "EzspNetworkScanType";
case "EzspStatus":
addImport(ezspStructurePackage + ".EzspStatus");
return "EzspStatus";
case "EmberStatus":
addImport(ezspStructurePackage + ".EmberStatus");
return "EmberStatus";
case "EmberNetworkParameters":
addImport(ezspStructurePackage + ".EmberNetworkParameters");
return "EmberNetworkParameters";
case "EmberNodeType":
addImport(ezspStructurePackage + ".EmberNodeType");
return "EmberNodeType";
case "EzspConfigId":
addImport(ezspStructurePackage + ".EzspConfigId");
return "EzspConfigId";
case "EmberNetworkStatus":
addImport(ezspStructurePackage + ".EmberNetworkStatus");
return "EmberNetworkStatus";
case "EmberKeyData":
addImport(ezspStructurePackage + ".EmberKeyData");
return "EmberKeyData";
case "EmberKeyType":
addImport(ezspStructurePackage + ".EmberKeyType");
return "EmberKeyType";
case "EmberDeviceUpdate":
addImport(ezspStructurePackage + ".EmberDeviceUpdate");
return "EmberDeviceUpdate";
case "EmberJoinDecision":
addImport(ezspStructurePackage + ".EmberJoinDecision");
return "EmberJoinDecision";
case "EmberMacPassthroughType":
addImport(ezspStructurePackage + ".EmberMacPassthroughType");
return "EmberMacPassthroughType";
case "EmberConcentratorType":
addImport(ezspStructurePackage + ".EmberConcentratorType");
return "EmberConcentratorType";
case "EzspValueId":
addImport(ezspStructurePackage + ".EzspValueId");
return "EzspValueId";
case "EzspExtendedValue":
addImport(ezspStructurePackage + ".EzspExtendedValue");
return "EzspExtendedValue";
case "EmberKeyStruct":
addImport(ezspStructurePackage + ".EmberKeyStruct");
return "EmberKeyStruct";
case "EmberPowerMode":
addImport(ezspStructurePackage + ".EmberPowerMode");
return "EmberPowerMode";
case "EmberGpAddress":
addImport(ezspStructurePackage + ".EmberGpAddress");
return "EmberGpAddress";
case "EmberGpSecurityLevel":
addImport(ezspStructurePackage + ".EmberGpSecurityLevel");
return "EmberGpSecurityLevel";
case "EmberGpKeyType":
addImport(ezspStructurePackage + ".EmberGpKeyType");
return "EmberGpKeyType";
case "EmberGpProxyTableEntry":
addImport(ezspStructurePackage + ".EmberGpProxyTableEntry");
return "EmberGpProxyTableEntry";
case "EmberGpSinkListEntry[":
addImport(ezspStructurePackage + ".EmberGpSinkListEntry");
return "EmberGpSinkListEntry";
case "EmberAesMmoHashContext":
addImport(ezspStructurePackage + ".EmberAesMmoHashContext");
return "EmberAesMmoHashContext";
case "EzspExtendedValueId":
case "EzspMfgTokenId":
case "EmberCertificateData":
case "EmberCertificate283k1Data":
case "EmberPublicKeyData":
case "EmberPublicKey283k1Data":
case "EmberPrivateKeyData":
case "EmberPrivateKey283k1Data":
case "EmberSmacData":
case "EmberLibraryId":
case "EmberLibraryStatus":
case "EmberTransientKeyData":
case "EmberGpSinkListEntry":
case "EmberGpSinkTableEntry":
case "EmberBeaconData":
case "EmberBeaconIterator":
case "EmberMulticastTableEntry":
case "EmberKeyStatus":
case "EmberMultiPhyRadioParameters":
addImport(ezspStructurePackage + "." + dataTypeLocal);
return dataTypeLocal + modifier;
default:
return dataTypeLocal + modifier;
}
}
protected String getTypeSerializer(String dataType) {
String dataTypeLocal = new String(dataType);
if (dataType.contains("[")) {
dataTypeLocal = dataTypeLocal.substring(0, dataTypeLocal.indexOf("[") + 1);
}
switch (dataTypeLocal) {
case "EmberCounterType":
case "uint8_t":
case "uint8_u":
return "UInt8";
case "EmberMulticastId":
case "EzspDecisionBitmask":
case "EmberNodeId":
case "uint16_t":
return "UInt16";
case "uint32_t":
case "EmberGpSecurityFrameCounter":
return "UInt32";
case "uint8_t[":
case "uint8_u[":
return "UInt8Array";
case "int8s":
return "Int8S";
case "uint16_t[":
return "UInt16Array";
case "Bool":
return "Boolean";
case "EmberEUI64":
return "EmberEui64";
case "bool":
return "Bool";
case "EmberAesMmoHashContext":
return "EmberAesMmoHashContext";
case "EzspValueId":
return "EzspValueId";
case "EmberKeyStruct":
return "EmberKeyStruct";
case "EmberPowerMode":
return "EmberPowerMode";
case "ExtendedPanId":
return "ExtendedPanId";
case "EmberGpAddress":
return "EmberGpAddress";
case "EmberGpSecurityLevel":
return "EmberGpSecurityLevel";
case "EmberGpKeyType":
return "EmberGpKeyType";
case "EmberGpProxyTableEntry":
return "EmberGpProxyTableEntry";
case "EmberGpSinkListEntry[":
return "EmberGpSinkListEntry";
case "EzspExtendedValueId":
case "EzspMfgTokenId":
case "EmberLibraryId":
case "EmberLibraryStatus":
case "EmberCertificateData":
case "EmberCertificate283k1Data":
case "EmberPublicKeyData":
case "EmberPublicKey283k1Data":
case "EmberPrivateKeyData":
case "EmberPrivateKey283k1Data":
case "EmberSmacData":
case "EmberTransientKeyData":
case "EmberGpSinkListEntry":
case "EmberGpSinkTableEntry":
case "EmberBeaconData":
case "EmberBeaconIterator":
case "EmberMulticastTableEntry":
case "EmberMultiPhyRadioParameters":
return dataTypeLocal;
default:
return dataType;
}
}
private void createEmberFrame(Protocol protocol) throws FileNotFoundException, UnsupportedEncodingException {
OutputStream stringWriter = new ByteArrayOutputStream();
PrintStream out = new PrintStream(stringWriter);
clearImports();
outputCopywrite(out);
out.println("package " + ezspPackage + ";");
out.println();
out.println("import java.lang.reflect.Constructor;");
out.println("import java.lang.reflect.InvocationTargetException;");
out.println("import java.util.HashMap;");
out.println("import java.util.Map;");
out.println();
out.println("import org.slf4j.Logger;");
out.println("import org.slf4j.LoggerFactory;");
// out.println();
// out.println("import " + ashPackage + ".AshFrameData;");
Map commandMap = new TreeMap<>();
for (Command command : protocol.commands) {
commandMap.put(command.name, command);
}
addImport(ezspCommandPackage + ".*");
outputImports(out);
out.println();
out.println("/**");
out.println(
" * The EmberZNet Serial Protocol (EZSP) is the protocol used by a host application processor to interact with the");
out.println(" * EmberZNet PRO stack running on a Network CoProcessor (NCP).");
out.println(" * ");
out.println(" * Reference: UG100: EZSP Reference Guide");
out.println(" *
");
out.println(" * An EZSP V4 Frame is made up as follows -:");
out.println(" *
");
out.println(" * - Sequence : 1 byte sequence number");
out.println(" *
- Frame Control: 1 byte");
out.println(" *
- Frame ID : 1 byte");
out.println(" *
- Parameters : variable length");
out.println(" *
");
out.println(" * ");
out.println(" * An EZSP V5+ Frame is made up as follows -:");
out.println(" *
");
out.println(" * - Sequence : 1 byte sequence number");
out.println(" *
- Frame Control: 1 byte");
out.println(" *
- Legacy Frame ID : 1 byte");
out.println(" *
- Extended Frame Control : 1 byte");
out.println(" *
- Frame ID : 1 byte");
out.println(" *
- Parameters : variable length");
out.println(" *
");
out.println(" *");
out.println(" * Note that this code is autogenerated. Manual changes may be overwritten.");
out.println(" *");
out.println(" * @author Chris Jackson");
out.println(" */");
out.println("public abstract class EzspFrame {");
out.println(" /**");
out.println(" * The logger");
out.println(" */");
out.println(" private final static Logger logger = LoggerFactory.getLogger(EzspFrame.class);");
out.println();
out.println(" /**");
out.println(" * The minimum supported version of EZSP");
out.println(" */");
out.println(" public static final int EZSP_MIN_VERSION = 4;");
out.println();
out.println(" /**");
out.println(" * The maximum supported version of EZSP");
out.println(" */");
out.println(" public static final int EZSP_MAX_VERSION = 13;");
out.println();
out.println(" /**");
out.println(" * The network ID bit shift");
out.println(" */");
out.println(" protected static final int EZSP_NETWORK_ID_SHIFT = 5;");
out.println();
out.println(" /**");
out.println(" * The network ID bit mask");
out.println(" */");
out.println(" protected static final int EZSP_NETWORK_ID_MASK = 0x60;");
out.println();
out.println(" /**");
out.println(" * The current version of EZSP being used");
out.println(" */");
out.println(" protected static int ezspVersion = EZSP_MIN_VERSION;");
out.println();
out.println(" /**");
out.println(" * Legacy frame ID for EZSP 5+");
out.println(" */");
out.println(" protected static final int EZSP_LEGACY_FRAME_ID = 0xFF;");
out.println();
out.println(" /**");
out.println(" * EZSP Frame Control Request flag");
out.println(" */");
out.println(" protected static final int EZSP_FC_REQUEST = 0x0000;");
out.println();
out.println(" /**");
out.println(" * EZSP Frame Control Response flag");
out.println(" */");
out.println(" protected static final int EZSP_FC_RESPONSE = 0x0080;");
out.println();
for (Command command : commandMap.values()) {
String reference = camelCaseToConstant(
command.name.substring(0, 1).toUpperCase() + command.name.substring(1));
out.println(" protected static final int FRAME_ID_" + reference + " = 0x"
+ String.format("%02X", command.id) + ";");
}
out.println();
out.println(" protected int sequenceNumber;");
out.println(" protected int frameControl;");
out.println(" protected int frameId = 0;");
out.println(" protected int networkId = 0;");
out.println(" protected boolean isResponse = false;");
out.println();
out.println(" private static Map> ezspHandlerMap = new HashMap>();");
out.println(" static {");
for (Command command : commandMap.values()) {
String className;
if (command.name.endsWith("Handler")) {
className = "Ezsp" + command.name.substring(0, 1).toUpperCase() + command.name.substring(1);
} else {
className = "Ezsp" + command.name.substring(0, 1).toUpperCase() + command.name.substring(1)
+ "Response";
}
String reference = camelCaseToConstant(
command.name.substring(0, 1).toUpperCase() + command.name.substring(1));
out.println(" ezspHandlerMap.put(FRAME_ID_" + reference + ", " + className + ".class);");
}
out.println(" }");
out.println();
out.println(" /**");
out.println(" * Sets the network ID (0 to 3)");
out.println(" *");
out.println(" * @param networkId the networkId");
out.println(" */");
out.println(" public void setNetworkId(int networkId) {");
out.println(" this.networkId = networkId;");
out.println(" }");
out.println();
out.println(" /**");
out.println(" * Gets the network ID (0 to 3)");
out.println(" *");
out.println(" * @return the networkId of this frame");
out.println(" */");
out.println(" public int getNetworkId() {");
out.println(" return networkId;");
out.println(" }");
out.println();
out.println(" /**");
out.println(" * Gets the 8 bit transaction sequence number");
out.println(" *");
out.println(" * @return sequence number");
out.println(" */");
out.println(" public int getSequenceNumber() {");
out.println(" return sequenceNumber;");
out.println(" }");
out.println();
out.println(" /**");
out.println(" * Checks if this frame is a response frame");
out.println(" *");
out.println(" * @return true if this is a response");
out.println(" */");
out.println(" public boolean isResponse() {");
out.println(" return isResponse;");
out.println(" }");
out.println();
out.println(" /**");
out.println(" * Gets the Ember frame ID for this frame");
out.println(" *");
out.println(" * @return the Ember frame Id");
out.println(" */");
out.println(" public int getFrameId() {");
out.println(" return frameId;");
out.println(" }");
out.println();
out.println(" /**");
out.println(" * Creates and {@link EzspFrameResponse} from the incoming data.");
out.println(" *");
out.println(" * @param data the int[] containing the EZSP data from which to generate the frame");
out.println(" * @return the {@link EzspFrameResponse} or null if the response can't be created.");
out.println(" */");
out.println(" public static EzspFrameResponse createHandler(int[] data) {");
out.println(" int frameId;");
out.println();
out.println(" try {");
out.println(" if (ezspVersion >= 8) {");
out.println(" frameId = data[3] + (data[4] << 8);");
out.println(" } else {");
out.println(" if (data[2] != 0xFF) {");
out.println(" frameId = data[2];");
out.println(" } else {");
out.println(" frameId = data[4];");
out.println(" }");
out.println(" }");
out.println(" } catch (ArrayIndexOutOfBoundsException e) {");
out.println(" logger.debug(\"EzspFrame error detecting the frame type: {}\", frameToString(data));");
out.println(" return null;");
out.println(" }");
out.println();
out.println(" Class> ezspClass = ezspHandlerMap.get(frameId);");
out.println(" if (ezspClass == null) {");
out.println(" return null;");
out.println(" }");
out.println();
out.println(" Constructor> ctor;");
out.println(" try {");
out.println(" ctor = ezspClass.getConstructor(int[].class);");
out.println(" EzspFrameResponse ezspFrame = (EzspFrameResponse) ctor.newInstance(data);");
out.println(" return ezspFrame;");
out.println(
" } catch (SecurityException | NoSuchMethodException | IllegalArgumentException | InstantiationException");
out.println(" | IllegalAccessException | InvocationTargetException e) {");
out.println(" Exception realE = e;");
out.println(" if (e instanceof InvocationTargetException) {");
out.println(" realE = (Exception) ((InvocationTargetException) e).getCause();");
out.println(" }");
out.println(
" logger.debug(\"EzspFrame error {} creating instance of frame: {}\", realE.getClass().getSimpleName(),");
out.println(" frameToString(data));");
out.println(" }");
out.println();
out.println(" return null;");
out.println(" }");
out.println();
out.println(" /**");
out.println(" * Set the EZSP version to use");
out.println(" *");
out.println(" * @param ezspVersion the EZSP protocol version");
out.println(" * @return true if the version is supported");
out.println(" */");
out.println(" public static boolean setEzspVersion(int ezspVersion) {");
out.println(" if (ezspVersion <= EZSP_MAX_VERSION && ezspVersion >= EZSP_MIN_VERSION) {");
out.println(" EzspFrame.ezspVersion = ezspVersion;");
out.println(" return true;");
out.println(" }");
out.println();
out.println(" return false;");
out.println(" }");
out.println();
out.println(" /**");
out.println(
" * Gets the current version of EZSP that is in use. This will default to the minimum supported version on startup");
out.println(" *");
out.println(" * @return the current version of EZSP");
out.println(" */");
out.println(" public static int getEzspVersion() {");
out.println(" return EzspFrame.ezspVersion;");
out.println(" }");
out.println();
out.println(" private static String frameToString(int[] inputBuffer) {");
out.println(" StringBuilder result = new StringBuilder();");
out.println(" for (int data : inputBuffer) {");
out.println(" result.append(String.format(\"%02X \", data));");
out.println(" }");
out.println(" return result.toString();");
out.println(" }");
out.println("}");
out.flush();
File packageFile = new File(sourceRootPath + ezspPackage.replace(".", "/"));
PrintStream outFile = getClassOut(packageFile, "EzspFrame");
outFile.print(stringWriter.toString());
outFile.flush();
outFile.close();
out.close();
}
}