All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.zsmartsystems.zigbee.dongle.ember.autocode.CommandGenerator Maven / Gradle / Ivy

The newest version!
/**
 * 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(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy