/** * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. */ /* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package org.thingml.networkplugins.c; import org.sintef.thingml.ExternalConnector; import org.sintef.thingml.Message; import org.sintef.thingml.Parameter; import org.sintef.thingml.helpers.AnnotatedElementHelper; import org.thingml.compilers.Context; import org.thingml.compilers.c.CCompilerContext; import org.thingml.compilers.spi.SerializationPlugin; import java.util.ArrayList; import java.util.List; import java.util.Set; /** * * @author sintef */ public class CMSPSerializerPlugin extends SerializationPlugin { CCompilerContext cctx; public CMSPSerializerPlugin() { super(); } @Override public SerializationPlugin clone() { return new CMSPSerializerPlugin(); } @Override public void setContext(Context ctx) { context = ctx; cctx = (CCompilerContext) context; } @Override public String generateSerialization(StringBuilder builder, String bufferName, Message m, ExternalConnector eco) { builder.append("byte " + bufferName + "[" + cctx.getMessageSerializationSize(m) + "];\n"); int HandlerCode = cctx.getHandlerCode(configuration, m); //TODO Relay HEADER to network layer builder.append(bufferName + "[0] = '<';\n"); builder.append(bufferName + "[1] = " + (cctx.getMessageSerializationSize(m) - 4) + ";\n"); builder.append(bufferName + "[2] = " + HandlerCode + " & 0xFF;\n\n"); int j = 3; for (Parameter pt : m.getParameters()) { builder.append("\n// parameter " + pt.getName() + "\n"); int i = cctx.getCByteSize(pt.getType(), 0); String v = pt.getName(); if (cctx.isPointer(pt.getType())) { // This should not happen and should be checked before. throw new Error("ERROR: Attempting to deserialize a pointer (for message " + m.getName() + "). This is not allowed."); } else { if (!AnnotatedElementHelper.isDefined(pt, "ignore", "true")) { builder.append("union u_" + v + "_t {\n"); builder.append(cctx.getCType(pt.getType()) + " p;\n"); builder.append("byte bytebuffer[" + cctx.getCByteSize(pt.getType(), 0) + "];\n"); builder.append("} u_" + v + ";\n"); builder.append("u_" + v + ".p = " + v + ";\n"); for (int k1 = 0; k1 < i; k1++) { builder.append(bufferName + "[" + j + "] = (u_" + v + ".bytebuffer[" + k1 + "] & 0xFF);\n"); j++; } } } } builder.append("byte crc = 0;\n"); for (int k = 1; k < (cctx.getMessageSerializationSize(m) - 1); k++) { builder.append("crc ^= " + bufferName + "[" + k + "];\n"); } builder.append(bufferName + "[" + j + "] = crc;\n"); j++; return j + ""; } @Override public void generateParserBody(StringBuilder builder, String bufferName, String bufferSizeName, Set<Message> messages, String sender, ExternalConnector eco) { builder.append(" byte msg_buf[" + bufferSizeName + "];\n"); builder.append(" msg_buf[0] = 1;\n"); builder.append(" msg_buf[1] = " + bufferName + "[1];\n"); builder.append(" uint16_t msgID = 256 + " + bufferName + "[1];\n"); builder.append(" uint16_t index = 2;\n"); builder.append(" switch(msgID) {\n"); for (Message m : messages) { builder.append(" case " + cctx.getHandlerCode(configuration, m) + ":\n"); int j = 2; for (Parameter pt : m.getParameters()) { for (int i = cctx.getCByteSize(pt.getType(), 0) - 1; i >= 0; i--) { builder.append(" msg_buf[index] = " + bufferName + "[" + (j + i) + "];\n"); builder.append(" index++;\n"); } j += cctx.getCByteSize(pt.getType(), 0); } builder.append(" break;\n"); } builder.append(" }\n"); builder.append(" externalMessageEnqueue((uint8_t *) msg_buf, size, " + sender + ");\n"); } @Override public String getPluginID() { return "CMSPSerializerPlugin"; } @Override public List<String> getTargetedLanguages() { List<String> res = new ArrayList<>(); res.add("posix"); res.add("arduino"); return res; } @Override public List<String> getSupportedFormat() { List<String> res = new ArrayList<>(); res.add("MSP"); return res; } }