Pārlūkot izejas kodu

Autowiggler mode added with matrix logging. Logging migrated to Log4J with the iZc logformatting

LH 2 gadi atpakaļ
vecāks
revīzija
ff08b3afef

+ 11 - 0
SenaBitWiggler/build.gradle

@@ -26,4 +26,15 @@ dependencies{
     api "org.yaml:snakeyaml:1.14"
     api("com.google.guava:guava:31.0.1-jre")
 	api( 'info.picocli:picocli:4.6.2')
+	api('io.github.ma1uta.matrix:client-impl:+')
+	api group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.+'
+	api group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.+'
+	api group: 'org.apache.logging.log4j', name: 'log4j-iostreams', version: '2.+'
+	api group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.+'
+	api group: 'org.apache.logging.log4j', name: 'log4j-jul', version: '2.+'
+
+
+	api('org.jboss.resteasy:resteasy-client-microprofile:4.6+')
+	api('org.jboss.resteasy:resteasy-jackson2-provider:4.6+')
+	api('javax.enterprise:cdi-api:1.2')
 }

+ 40 - 0
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/Configuration.java

@@ -4,6 +4,46 @@ public class Configuration {
     private String BlueLabPath;
     private String SoxPath;
 
+    private boolean MatrixEnabled = false;
+
+    private String MatrixUser;
+
+    private String MatrixPassword;
+
+    private String MatrixDomain;
+
+    public String getMatrixDomain() {
+        return MatrixDomain;
+    }
+
+    public void setMatrixDomain(String matrixDomain) {
+        MatrixDomain = matrixDomain;
+    }
+
+    public boolean isMatrixEnabled() {
+        return MatrixEnabled;
+    }
+
+    public String getMatrixPassword() {
+        return MatrixPassword;
+    }
+
+    public String getMatrixUser() {
+        return MatrixUser;
+    }
+
+    public void setMatrixEnabled(boolean matrixEnabled) {
+        MatrixEnabled = matrixEnabled;
+    }
+
+    public void setMatrixPassword(String matrixPassword) {
+        MatrixPassword = matrixPassword;
+    }
+
+    public void setMatrixUser(String matrixUser) {
+        MatrixUser = matrixUser;
+    }
+
     public String getBlueLabPath() {
         return BlueLabPath;
     }

+ 32 - 7
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/EntryPoint.java

@@ -2,6 +2,11 @@ package de.nplusc.izc.senabitwiggler;
 
 import java.io.*;
 
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.LoggerConfig;
 import org.yaml.snakeyaml.Yaml;
 import picocli.CommandLine;
 import picocli.CommandLine.Command;
@@ -11,6 +16,8 @@ import picocli.CommandLine.Parameters;
 @Command(mixinStandardHelpOptions = true, version = "Sena Firmware Hacking Utiility")
 public class EntryPoint implements Runnable
 {
+    private static final Logger l = LogManager.getLogger();
+
     @Parameters(index = "0", description = "Mode for the Program. Valid values: ${COMPLETION-CANDIDATES}")
     private Modes mode;
 
@@ -34,6 +41,8 @@ public class EntryPoint implements Runnable
     public static String SoxPath = "";
     public static String BlueLabPath = "";
 
+    public static Configuration c;
+
     public static final String APPDIR = new File(EntryPoint.class.getProtectionDomain().getCodeSource().getLocation().getPath()).getParentFile().getParent();
 
     public static void main(String[] args)
@@ -46,9 +55,10 @@ public class EntryPoint implements Runnable
                 Configuration config = y.loadAs(new FileReader(cfg),Configuration.class);
                 SoxPath=config.getSoxPath();
                 BlueLabPath=config.getBlueLabPath();
-            } catch (FileNotFoundException e) {
-                System.err.println("Hurz");
-                e.printStackTrace();
+                c=config;
+                y.dump(config, new FileWriter(cfg));
+            } catch (IOException e) {
+                l.catching(e);
             }
         }
         else
@@ -58,9 +68,9 @@ public class EntryPoint implements Runnable
             config.setSoxPath("sox");
             try {
                 y.dump(config, new FileWriter(cfg));
-                System.err.println("Configuration needed. Check the generated config.yml");
+                l.error("Configuration needed. Check the generated config.yml");
             } catch (IOException e) {
-                System.err.println("Failed to initialize config");
+                l.error("Failed to initialize config");
                 e.printStackTrace();
             }
             System.exit(0);
@@ -73,7 +83,22 @@ public class EntryPoint implements Runnable
 
     @Override
     public void run() {
-        //TODO check and init config file
+        System.setProperty("java.util.logging.manager", "org.apache.logging.log4j.jul.LogManager"); //HACK to catch java.util.logging loggers
+        LoggerContext cx = (LoggerContext) LogManager.getContext(false);
+        org.apache.logging.log4j.core.config.Configuration config = cx.getConfiguration();
+
+        LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
+
+        if (verbose)
+        {
+            loggerConfig.setLevel(Level.TRACE);
+        }
+        else
+        {
+            loggerConfig.setLevel(Level.INFO);
+        }
+
+
         switch(mode)
         {
             case ExtractSenaBin:
@@ -81,7 +106,7 @@ public class EntryPoint implements Runnable
                     Utils.makeSureThatOutFolderIsCreated(output.getPath());
                     FirmwareWrapperExtraction.extractFirmwareLong(input,output.getPath());
                 } catch (InputInvalidException e) {
-                    System.out.println("Zarf! File was bad");
+                    l.error("Zarf! File was bad");
                     e.printStackTrace();
                 }
                 break;

+ 10 - 0
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/Firmware.java

@@ -11,6 +11,16 @@ public class Firmware {
     private int minor;
     private int patch;
 
+    private String roomid;
+
+    public String getRoomid() {
+        return roomid;
+    }
+
+    public void setRoomid(String roomid) {
+        this.roomid = roomid;
+    }
+
     public int getMajor() {
         return major;
     }

+ 170 - 22
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/FirmwareAutoDumper.java

@@ -1,5 +1,11 @@
 package de.nplusc.izc.senabitwiggler;
 
+import io.github.ma1uta.matrix.client.StandaloneClient;
+import io.github.ma1uta.matrix.client.model.room.CreateRoomRequest;
+import io.github.ma1uta.matrix.event.content.RoomPowerLevelsContent;
+import io.github.ma1uta.matrix.impl.exception.MatrixException;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 import org.yaml.snakeyaml.DumperOptions;
 import org.yaml.snakeyaml.TypeDescription;
 import org.yaml.snakeyaml.Yaml;
@@ -12,17 +18,19 @@ import java.io.*;
 import java.nio.file.CopyOption;
 import java.nio.file.Files;
 import java.nio.file.StandardCopyOption;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
 import java.util.*;
 
 public class FirmwareAutoDumper
 {
-
+    private static final Logger l = LogManager.getLogger();
     static Statefile state = null;
     static File outfolder_base;
     public static final boolean IA_UPLOAD_ENABLED = false;
     public static final boolean DUMMY_MODE = false;
     public static PrintStream dummydownloadfake = null;
-    public static Set<String> supprCache = new HashSet<>();
+    public static HashMap<String,FirmwareVersion> supprCache = new HashMap<>();
 
     public static void pullFirmwares(File statefile, File outfolder, boolean deepmode)
     {
@@ -32,6 +40,7 @@ public class FirmwareAutoDumper
             {
                 dummydownloadfake = new PrintStream(new FileOutputStream(new File(outfolder,"dummy.log")));
             }
+
             Representer representer = new Representer();
             representer.addClassTag(Firmware.class, new Tag("!FW"));
             representer.addClassTag(FirmwareVersion.class, new Tag("!FWV"));
@@ -49,8 +58,7 @@ public class FirmwareAutoDumper
                     Yaml internal = new Yaml(constructor);
                     state = (Statefile) internal.load(new FileReader(statefile));
                 } catch (FileNotFoundException e) {
-                    System.err.println("Hurz");
-                    e.printStackTrace();
+                    l.catching(e);
                 }
             }
             else
@@ -60,6 +68,10 @@ public class FirmwareAutoDumper
             }
 
             File outfolder_tmp = new File(outfolder,"tmp");
+            if(!DUMMY_MODE)
+            {
+                new File(outfolder_tmp,"Firmware").delete();
+            }
             File downloadFolderBase = new File(outfolder_base,"downloadstage");
             downloadFolderBase.mkdirs();
             File fw = new File(outfolder_tmp,"Firmware");
@@ -129,11 +141,16 @@ public class FirmwareAutoDumper
             br.close();
             y.dump(state,new FileWriter(statefile));
             if(!DUMMY_MODE)
+            {
                 new File(outfolder_tmp,"Firmware").delete();
+                pushToMatrix();
+            }
             if(DUMMY_MODE)
             {
                 dummydownloadfake.close();
             }
+
+            y.dump(state,new FileWriter(statefile));
         }
         catch (IOException ex)
         {
@@ -141,6 +158,138 @@ public class FirmwareAutoDumper
         }
     }
 
+    private static void pushToMatrix()
+    {
+        if(!EntryPoint.c.isMatrixEnabled())
+        {
+            //skip all if matrix is off.
+            return;
+        }
+        StandaloneClient mxClient = new StandaloneClient.Builder().domain(EntryPoint.c.getMatrixDomain()).build();
+        mxClient.auth().login(EntryPoint.c.getMatrixUser(), EntryPoint.c.getMatrixPassword().toCharArray());
+        if(state.getGeneralRoomId()==null)
+        {
+            l.info("Create Matrix Room General");
+            CreateRoomRequest r = new CreateRoomRequest();
+            r.setName("Sena Full Logstream");
+            r.setRoomAliasName("SenaFirmwareAll");
+            RoomPowerLevelsContent lvls = new RoomPowerLevelsContent();
+            lvls.setEventsDefault((byte)1); //readonly except for the BitWiggler
+            r.setPowerLevelContentOverride(lvls);
+            r.setVisibility("public");
+            state.setGeneralRoomId(mxClient.room().create(r).getRoomId());
+        }
+
+        if(state.getOtherRoomId()==null)
+        {
+            l.info("Create Matrix Room Catchall");
+            CreateRoomRequest r = new CreateRoomRequest();
+            r.setName("Sena Other Logstream");
+            r.setRoomAliasName("SenaFirmwareOther");
+            RoomPowerLevelsContent lvls = new RoomPowerLevelsContent();
+            lvls.setEventsDefault((byte)1); //readonly except for the BitWiggler
+            r.setPowerLevelContentOverride(lvls);
+            r.setVisibility("public");
+            state.setOtherRoomId(mxClient.room().create(r).getRoomId());
+        }
+
+        state.getFirmwares().forEach((k,v)->
+        {
+            if(v.getRoomid()==null)
+            {
+                l.info("Create Matrix Room for:"+k);
+                CreateRoomRequest r = new CreateRoomRequest();
+                r.setName("Sena Logstream: "+v.getDeviceId());
+                r.setRoomAliasName("SenaStream"+k);
+                RoomPowerLevelsContent lvls = new RoomPowerLevelsContent();
+                lvls.setEventsDefault((byte)1); //readonly except for the BitWiggler
+                r.setPowerLevelContentOverride(lvls);
+                r.setVisibility("public");
+                while(v.getRoomid()==null)
+                {
+                    try {
+
+                        v.setRoomid(mxClient.room().create(r).getRoomId());
+                    }
+                    catch(MatrixException e)
+                    {
+
+                    }
+                    if(v.getRoomid()==null)
+                    {
+                        try {
+                            Thread.sleep(2000);
+                        } catch (InterruptedException e) {
+                            e.printStackTrace();
+                        }
+                    }
+                }
+            }
+
+            List<String> keys = new ArrayList<>(v.getVersions().keySet());
+            keys.sort((x,y)->
+            {
+                var vr = v.getVersions();
+                var version1 = vr.get(x);
+                var version2 = vr.get(y);
+                if(version1.getMajor()< version2.getMajor()) {
+                    return -1;
+                }
+                if(version1.getMajor()> version2.getMajor()) {
+                    return 1;
+                }
+                if(version1.getMinor()< version2.getMinor()) {
+                    return -1;
+                }
+                if(version1.getMinor()> version2.getMinor()) {
+                    return 1;
+                }
+                if(version1.getPatch()< version2.getPatch()) {
+                    return -1;
+                }
+                if(version1.getPatch()> version2.getPatch()) {
+                    return 1;
+                }
+                return 0;
+            });
+            for (var v2p : keys) {
+                final var v2 = v.getVersions().get(v2p); //HAXX
+                LinkedList<Runnable> messageActions = new LinkedList<>();
+
+                if(!v2.isFiller())
+                {
+                    String version = v2.getMajor()+"."+v2.getMinor()+"."+v2.getPatch();
+                    Date ts = v2.getServerCreationDate();
+                    TimeZone tz = TimeZone.getTimeZone("UTC");
+                    DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'"); // Quoted "Z" to indicate UTC, no timezone offset
+                    df.setTimeZone(tz);
+                    String date = df.format(ts);
+                    String msg = "Detected new Version: "+version+" for "+k+" uploaded at: "+date;
+
+                    if(v2.isHidden())
+                    {
+                        msg = "Guessed new hidden Version: "+version+" for "+k+" uploaded at: "+date;
+                    }
+                    if((!v2.isHidden()&&v2.getNotificationState()==MatrixState.SENT_PRELIM)||v2.getNotificationState()==MatrixState.TODO)
+                    {
+                        final String msg2 = msg;
+                        messageActions.add(()->
+                        {
+                            l.info("Push: "+msg2);
+                            mxClient.event().sendMessage(v.getRoomid(), msg2);
+                            mxClient.event().sendMessage(state.getGeneralRoomId(), msg2);
+                            v2.setNotificationState(v2.isHidden()?MatrixState.SENT_PRELIM:MatrixState.SENT);
+                        });
+                    }
+                }
+                messageActions.iterator().forEachRemaining(runnable -> runnable.run());
+            }
+        });
+        mxClient.auth().logout();
+    }
+
+
+
     private static int[] splitVersionAndPullFW(String filename,HashMap<String,FirmwareVersion> knownVersions, boolean deepmode) throws IOException {
         String[] magic = filename.split("-v");
         boolean fuckingoddity = false;
@@ -213,9 +362,9 @@ public class FirmwareAutoDumper
             String prefix,
             String suffix,
             HashMap<String,FirmwareVersion> knownVersions) throws IOException {
-        System.out.println(major+"--"+minor+"--"+patch);
+        l.info(major+"--"+minor+"--"+patch);
         List<FirmwareVersion> temp = new ArrayList<>();
-        System.out.println(prefix+"."+major+"."+minor+"."+patch+"."+suffix);
+        l.info(prefix+"."+major+"."+minor+"."+patch+"."+suffix);
 
         while(major>=1&&minor>=0&&patch>=0) //older versions won't be bruteforced, check for existence in the index prevents a redownload.
         {
@@ -266,13 +415,15 @@ public class FirmwareAutoDumper
         f.setMinor(minor);
         f.setPatch(patch);
         File downloadFolderBase = new File(outfolder_base,"downloadstage");
-        if(supprCache.contains(fwname)) //leaves a "fake entry" when 2 different deviceIDs would lead to the same filename
+        if(supprCache.containsKey(fwname)) //leaves a "fake entry" when 2 different deviceIDs would lead to the same filename
         {
-            f.setFiller(true);
-            f.setServerCreationDate(new Date(0));
+            l.info("Fakerfuck");
+            FirmwareVersion f2 =  supprCache.get(fwname);
+            f.setFiller(false);
+            f.setServerCreationDate(f2.getServerCreationDate());
             return f;
         }
-        supprCache.add(fwname); // banning a filename from rescan/redownload
+        supprCache.put(fwname,f); // banning a filename from rescan/redownload
         //if(true) return f;
         if(!DUMMY_MODE)
         {
@@ -285,24 +436,16 @@ public class FirmwareAutoDumper
         {
             dummydownloadfake.println("http://firmware.sena.com/senabluetoothmanager/"+fwname);
         }
-        System.err.println("New Version spotted:"+fwname); //intentionally a output. that should be mailed by the cron daemon if its
+        l.info("New Version spotted:"+fwname);
         File dlf = new File(downloadFolderBase,fwname);
         File dst = new File(outfolder_base,fwname);
-        if(dlf.exists()&&!dst.exists())
+        if(dlf.exists())
         {
             f.setFiller(false);
             f.setServerCreationDate(new Date(dlf.lastModified()));
-            Files.copy(dlf.toPath(),dst.toPath());
-
-            if(IA_UPLOAD_ENABLED)
+            if(!dst.exists())
             {
-                Utils.runTool(downloadFolderBase,
-                        "ia",
-                        "upload",
-                        "sena-firmware-files",
-                        "--no-derive",
-                        fwname
-                );
+                Files.copy(dlf.toPath(),dst.toPath());
             }
         }
         else
@@ -314,6 +457,9 @@ public class FirmwareAutoDumper
     }
 
     private static void peekNext(String synthesizedFileName, String synthesizedFileNameShort, int major, int minor, int patch, HashMap<String,FirmwareVersion> knownVersions) throws IOException {
+        l.info("peekstate:");
+        l.info(knownVersions.containsKey(synthesizedFileName));
+        l.info(knownVersions.containsKey(synthesizedFileNameShort));
         if(!(knownVersions.containsKey(synthesizedFileName)||knownVersions.containsKey(synthesizedFileNameShort))) // only re-poking if nothing was there yet.
         {
             FirmwareVersion nextMajor = getFirmware(major,minor,patch,true,synthesizedFileName);
@@ -325,8 +471,10 @@ public class FirmwareAutoDumper
                     synthesizedFileName = synthesizedFileNameShort;
                 }
             }
+            l.info("peekstate:"+nextMajor.isFiller());
             if(!nextMajor.isFiller())
             {
+                l.info("SUCCESS for:"+synthesizedFileName);
                 knownVersions.put(synthesizedFileName,nextMajor);
             }
         }

+ 10 - 0
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/FirmwareVersion.java

@@ -10,6 +10,16 @@ public class FirmwareVersion {
     private int patch;
     private boolean hidden;
 
+    private MatrixState NotificationState = MatrixState.TODO;
+
+    public MatrixState getNotificationState() {
+        return NotificationState;
+    }
+
+    public void setNotificationState(MatrixState notificationState) {
+        NotificationState = notificationState;
+    }
+
     // signifies that a version is not a valid one and only "inserted" due to the guesser going over it. prevents re-guessing;
     private boolean filler;
 

+ 3 - 0
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/FirmwareWrapperExtraction.java

@@ -2,6 +2,8 @@ package de.nplusc.izc.senabitwiggler;
 
 import com.google.common.base.Charsets;
 import com.google.common.primitives.Longs;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 import org.yaml.snakeyaml.Yaml;
 
 import java.io.*;
@@ -9,6 +11,7 @@ import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 
 public class FirmwareWrapperExtraction {
+    private static final Logger l = LogManager.getLogger();
     public static void assembleFirmware(File output, String inputfolder)
     {
         Yaml y = new Yaml();

+ 22 - 19
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/FlashFSUnWiggler.java

@@ -2,6 +2,8 @@ package de.nplusc.izc.senabitwiggler;
 
 import com.google.common.primitives.Ints;
 import com.google.common.primitives.Shorts;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -10,6 +12,7 @@ import java.io.RandomAccessFile;
 import java.util.Random;
 
 public class FlashFSUnWiggler {
+    private static final Logger l = LogManager.getLogger();
     private static class FileMetadata
     {
         private int offset;
@@ -30,8 +33,8 @@ public class FlashFSUnWiggler {
             if(sizeFile>f.length())
             {
 
-                System.out.println(sizeFile);
-                System.err.println("ZOINKS!!!, mismatch");
+                l.info(sizeFile);
+                l.info("ZOINKS!!!, mismatch");
                 return;
             }
             f.read(javaisDipshit);
@@ -43,13 +46,13 @@ public class FlashFSUnWiggler {
                 f.read(javaisDipshit);
                 int sizeAndFlags = Ints.fromBytes(javaisDipshit[3],javaisDipshit[2],javaisDipshit[1],javaisDipshit[0]);
                 int size = sizeAndFlags&0x00FFFFFF;
-                System.out.println(sizeAndFlags);
-                System.out.println(size);
+                l.info(sizeAndFlags);
+                l.info(size);
 
                 fmd.offset_fname=size;
                 if((sizeAndFlags&0xFF000000)<0)
                 {
-                    System.out.println("dir");
+                    l.info("dir");
                     fmd.is_dir=true;
                 }
                 f.read(javaisDipshit);
@@ -89,7 +92,7 @@ public class FlashFSUnWiggler {
                 else
                 {
 
-                    System.out.println("Reading:"+fmd.parentpath+fmd.filename+"("+fmd.length+")@"+fmd.offset);
+                    l.info("Reading:"+fmd.parentpath+fmd.filename+"("+fmd.length+")@"+fmd.offset);
                     byte[] filecontent = new byte[fmd.length];
                     if(fmd.length>0)
                     {
@@ -128,8 +131,8 @@ public class FlashFSUnWiggler {
             if((sizeFile*2)>f.length())
             {
 
-                System.out.println(sizeFile);
-                System.err.println("ZOINKS!!!, mismatch");
+                l.info(sizeFile);
+                l.info("ZOINKS!!!, mismatch");
                 return;
             }
             byte[] background = new byte[(int)f.length()];
@@ -147,9 +150,9 @@ public class FlashFSUnWiggler {
 
             f.read(javaisDipshit);
             int countFileRecords = (Ints.fromBytes(javaisDipshit[2],javaisDipshit[3],javaisDipshit[0],javaisDipshit[1]) &0x00FFFFFF);
-            System.out.println(countFileRecords);
+            l.info(countFileRecords);
             int countFileRecordsXXX = (Ints.fromBytes(javaisDipshit[1],javaisDipshit[0],javaisDipshit[3],javaisDipshit[2])&0x00FFFFFF);
-            System.out.println(countFileRecordsXXX);
+            l.info(countFileRecordsXXX);
             boobs.write(fillershort);
             boobs.seek(10);
             f.seek(10);
@@ -165,13 +168,13 @@ public class FlashFSUnWiggler {
                 f.read(javaisDipshit);
                 int sizeAndFlags = Ints.fromBytes(javaisDipshit[0],javaisDipshit[1],javaisDipshit[2],javaisDipshit[3]);
                 int size = sizeAndFlags&0x00FFFFFF;
-                System.out.println("SZFlg>>"+sizeAndFlags);
-                System.out.println("SZExtr>>"+size);
+                l.info("SZFlg>>"+sizeAndFlags);
+                l.info("SZExtr>>"+size);
 
                 fmd.offset_fname=size;
                 if((sizeAndFlags&0xFF000000)<0)
                 {
-                    System.out.println("dir");
+                    l.info("dir");
                     fmd.is_dir=true;
                 }
                 f.read(javaisDipshit);
@@ -220,7 +223,7 @@ public class FlashFSUnWiggler {
                         int subfiles = fmd.offset+j-1;
                         if(subfiles==-1)
                         {
-                            System.out.println("WTF?");
+                            l.info("WTF?");
                         }
                         files[subfiles].parentpath=fmd.parentpath+fmd.filename;
                     }
@@ -228,7 +231,7 @@ public class FlashFSUnWiggler {
                 else
                 {
 
-                    System.out.println("Reading:"+fmd.parentpath+fmd.filename+"("+fmd.length+")@"+fmd.offset);
+                    l.info("Reading:"+fmd.parentpath+fmd.filename+"("+fmd.length+")@"+fmd.offset);
                     byte[] filecontent = new byte[fmd.length];
                     if(fmd.length>0)
                     {
@@ -262,7 +265,7 @@ public class FlashFSUnWiggler {
 
     public static void unpackQCC512DFU(File firmware, File outfolder)
     {
-        System.out.println("0x00!");
+        l.info("0x00!");
         try (RandomAccessFile f = new RandomAccessFile(firmware,"r"))
         {
             outfolder.mkdirs();
@@ -276,16 +279,16 @@ public class FlashFSUnWiggler {
             {
                 if(f.readInt() != 1346458196)
                 {
-                    System.out.println("Zarf!");
+                    l.info("Zarf!");
                     break; //end of file
                 }
                 if(f.readInt() != 1145132097)
                 {
-                    System.out.println("Zarf2!");
+                    l.info("Zarf2!");
                     break; //end of file
                 }
                 int sizeData = f.readInt();
-                System.out.println("Reading" +sizeData);
+                l.info("Reading" +sizeData);
                 byte[] innerFile = new byte[sizeData];
                 f.read(innerFile);
                 RandomAccessFile fo = new RandomAccessFile(new File(outfolder,i+".dat"),"rw");

+ 4 - 0
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/Jailbreaker.java

@@ -1,10 +1,14 @@
 package de.nplusc.izc.senabitwiggler;
 
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
 import java.io.File;
 import java.io.IOException;
 
 public class Jailbreaker {
 
+    private static final Logger l = LogManager.getLogger();
     private static String nvscmd = EntryPoint.BlueLabPath+"nvscmd";
     private static String pscli = EntryPoint.BlueLabPath+"pscli";
 

+ 20 - 0
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/MatrixState.java

@@ -0,0 +1,20 @@
+package de.nplusc.izc.senabitwiggler;
+
+public enum MatrixState {
+    /**
+     * used for guessed versions. Version will be renotified if its released
+     */
+    SENT_PRELIM,
+    /**
+     * released version, notified on matrix
+     */
+    SENT,
+    /**
+     * used for fake versions.
+     */
+    SKIPPED,
+    /**
+     * Not yet published
+     */
+    TODO
+}

+ 8 - 4
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/PromptHandlerSuite.java

@@ -1,5 +1,7 @@
 package de.nplusc.izc.senabitwiggler;
 
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 import org.yaml.snakeyaml.Yaml;
 
 import javax.sound.midi.Patch;
@@ -15,19 +17,21 @@ import java.util.*;
 import static de.nplusc.izc.senabitwiggler.Utils.runTool;
 
 public class PromptHandlerSuite {
+
+    private static final Logger l = LogManager.getLogger();
     public static void handlePrompts(File firmware, File outfolder, String headsetid,boolean deep) throws InputInvalidException {
         String devicefile = EntryPoint.APPDIR+File.separator+"devices"+File.separator+headsetid+".device.yml";
         if(!(new File(devicefile).exists()))
         {
             File f =  new File(EntryPoint.APPDIR+File.separator+"devices");
-            System.out.println("Invalid Headset reference: Valid values are");
+            l.error("Invalid Headset reference: Valid values are");
             try {
                 Files.walk(f.toPath(), 1).forEach(p ->
                 {
                     String fn = p.getFileName().toString();
                     if(fn.endsWith(".device.yml"))
                     {
-                        System.out.println(fn.replace(".device.yml",""));
+                        l.error(fn.replace(".device.yml",""));
                     }
                 });
             } catch (IOException e) {
@@ -133,14 +137,14 @@ public class PromptHandlerSuite {
             if(!(new File(devicefile).exists()))
             {
                 File f =  new File(EntryPoint.APPDIR+File.separator+"devices");
-                System.out.println("Invalid Headset reference: Valid values are");
+                l.error("Invalid Headset reference: Valid values are");
                 try {
                     Files.walk(f.toPath(), 1).forEach(p ->
                     {
                         String fn = p.getFileName().toString();
                         if(fn.endsWith(".device.yml"))
                         {
-                            System.out.println(fn.replace(".device.yml",""));
+                            l.error(fn.replace(".device.yml",""));
                         }
                     });
                 } catch (IOException e) {

+ 20 - 0
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/Statefile.java

@@ -14,4 +14,24 @@ public class Statefile {
     public void setFirmwares(HashMap<String, Firmware> firmwares) {
         this.firmwares = firmwares;
     }
+
+    private String generalRoomId;
+
+    private String otherRoomId;
+
+    public String getGeneralRoomId() {
+        return generalRoomId;
+    }
+
+    public void setGeneralRoomId(String generalRoomId) {
+        this.generalRoomId = generalRoomId;
+    }
+
+    public String getOtherRoomId() {
+        return otherRoomId;
+    }
+
+    public void setOtherRoomId(String otherRoomId) {
+        this.otherRoomId = otherRoomId;
+    }
 }

+ 4 - 1
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/Utils.java

@@ -1,6 +1,8 @@
 package de.nplusc.izc.senabitwiggler;
 
 import com.google.common.primitives.Longs;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 
 import javax.swing.*;
 import java.io.File;
@@ -10,6 +12,7 @@ import java.util.Arrays;
 import java.util.Locale;
 
 public class Utils {
+    private static final Logger l = LogManager.getLogger();
     public static byte[] LongToRawBytes(long l)
     {
         byte[] tmp = Longs.toByteArray(l);
@@ -37,7 +40,7 @@ public class Utils {
         {
             if(!od.mkdirs())
             {
-                System.err.println("WTF! somethint ate shit");
+                l.error("WTF! somethint ate shit");
                 return;
             }
         }

+ 7 - 4
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/VmAppFIleExtraction.java

@@ -3,11 +3,14 @@ package de.nplusc.izc.senabitwiggler;
 import com.google.common.primitives.Ints;
 import com.google.common.primitives.Longs;
 import com.google.common.primitives.Shorts;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 import org.yaml.snakeyaml.Yaml;
 
 import java.io.*;
 
 public class VmAppFIleExtraction {
+    private static final Logger l = LogManager.getLogger();
     public static void extractVmImage(File input, String output)
     {
         byte filler = 0x00;
@@ -17,7 +20,7 @@ public class VmAppFIleExtraction {
             long len = f.length()/2;
             if(len>Integer.MAX_VALUE)
             {
-                System.out.println("Ugggh, File too big");
+                l.error("Ugggh, File too big");
                 return;
             }
 
@@ -29,7 +32,7 @@ public class VmAppFIleExtraction {
             }
             if(Utils.xorsum(checksumarray)!=0)
             {
-                System.err.println("Smells like Dead Beef, the data seems to be corrupt");
+                l.error("Smells like Dead Beef, the data seems to be corrupt");
                 System.exit(1);
             }
             f.seek(0);
@@ -116,7 +119,7 @@ public class VmAppFIleExtraction {
             long len = f.length()/2;
             if(len>Integer.MAX_VALUE)
             {
-                System.out.println("Ugggh, File too big");
+                System.out.pri ntln("Ugggh, File too big");
                 return;
             }
 
@@ -128,7 +131,7 @@ public class VmAppFIleExtraction {
             }
             if(Utils.xorsum(checksumarray)!=0)
             {
-                System.err.println("Smells like Dead Beef, the data seems to be corrupt");
+                System.err.prin tln("Smells like Dead Beef, the data seems to be corrupt");
                 System.exit(1);
             }
             f.seek(0);

+ 18 - 16
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/XAPDisAsm.java

@@ -2,6 +2,8 @@ package de.nplusc.izc.senabitwiggler;
 
 import com.google.common.primitives.Ints;
 import com.google.common.primitives.Shorts;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 
 import java.io.*;
 import java.util.ArrayList;
@@ -14,7 +16,7 @@ interface OpCodeMangler
 }
 
 public class XAPDisAsm {
-
+    private static final Logger l = LogManager.getLogger();
     private static HashMap<String,String> labels = new HashMap<>();
 
     private static OpCodeMangler brxl = (modifier,opcode,address)->{
@@ -33,7 +35,7 @@ public class XAPDisAsm {
             badOpCode += (Utils.bytesToHex(Shorts.toByteArray(opcode[i])));
         }
         String invalidCode = OpcodeAddressRangeToString(address,opcode.length+(modified?1:0))+":Invalid OpCode: "+badOpCode;
-        System.err.println(invalidCode);
+        l.info(invalidCode);
         return invalidCode;
     };
     public static OpCodeMangler[] manglers = new OpCodeMangler[256];
@@ -51,12 +53,12 @@ public class XAPDisAsm {
                 for(int i=0;i<opcode.length;i++)
                 {
                     byte[] opcodeWord = Shorts.toByteArray(opcode[i]);
-                    if(EntryPoint.verbose)System.out.println(opcodeWord[0]);
+                    l.trace(opcodeWord[0]);
                     opcodeValues[i]=opcodeWord[0];
                     opcodeReal=(opcodeWord[1]); //stompy stomp, only keeps the last
                 }
                 String rawValue = Utils.bytesToHex(opcodeValues);
-                if(EntryPoint.verbose)System.out.println(rawValue);
+                l.trace(rawValue);
 
                 int valueUnsigned = XAPDisAsmGeneratedCode.unsignedCounts.get(rawValue);
                 int valueSigned =XAPDisAsmGeneratedCode.signedCounts.get(rawValue);
@@ -158,7 +160,7 @@ public class XAPDisAsm {
                     opcodeReal=(opcodeWord[1]); //stompy stomp, only keeps the last
                 }
                 String rawVal = Utils.bytesToHex(opcodeValues);
-                if(EntryPoint.verbose)System.out.println(rawVal);
+                l.trace(rawVal);
                 int valueUnsigned = XAPDisAsmGeneratedCode.unsignedCounts.get(rawVal);
                 int valueSigned =XAPDisAsmGeneratedCode.signedCounts.get(Utils.bytesToHex(opcodeValues));
                 String register = "";
@@ -834,15 +836,15 @@ public class XAPDisAsm {
     private static int untwiddleOpcodeParamBra(byte[] opcode,int opcodelocation)
     {
         int out = opcode[0];
-        if(EntryPoint.verbose)System.out.println(out);
-        if(EntryPoint.verbose)System.out.println(String.format("0x%08X", out));
+        l.trace(out);
+        l.trace(String.format("0x%08X", out));
         for(int i=1;i<opcode.length;i++)
         {
             out=out<<8;
             out+=opcode[i];
-            if(EntryPoint.verbose)System.out.println(out);
-            if(EntryPoint.verbose)System.out.println(opcode[i]);
-            if(EntryPoint.verbose)System.out.println(String.format("0x%08X", out));
+            l.trace(out);
+            l.trace(opcode[i]);
+            l.trace(String.format("0x%08X", out));
         }
         out=out+opcodelocation;
         out = out &0x00FFFFFF;
@@ -939,9 +941,9 @@ public class XAPDisAsm {
             for(int i=0;i<assemblyLength;i++)
             {
                 Short word = f.readShort();
-                if(EntryPoint.verbose)System.out.println("READ:"+ (word&0xff));
-                if(EntryPoint.verbose)System.out.println(addressToString(i));
-                if(EntryPoint.verbose)System.out.println(addressToString(baseAddressLastOpcode));
+                l.trace("READ:"+ (word&0xff));
+                l.trace(addressToString(i));
+                l.trace(addressToString(baseAddressLastOpcode));
                 opcodeHoldingBay.add(word);
                 if(word==(short)0xfe09) //specialcasing one specific opcode
                 {
@@ -972,13 +974,13 @@ public class XAPDisAsm {
                                 opcode[j]=opcodeHoldingBay.get(j);
                             }
                         }
-                        if(EntryPoint.verbose)System.out.println("Mangling Opcode with length"+opcode.length);
+                        l.trace("Mangling Opcode with length"+opcode.length);
                         try{
                             disassembled.println(manglers[word&0xff].mangleOpCode(modifier,opcode,baseAddressLastOpcode));
                         }
                         catch(Exception e)
                         {
-                            System.err.println(invalid.mangleOpCode(modifier,opcode,baseAddressLastOpcode));
+                            l.info(invalid.mangleOpCode(modifier,opcode,baseAddressLastOpcode));
                             disassembled.println(invalid.mangleOpCode(modifier,opcode,baseAddressLastOpcode));
                             //System.exit(-1);
                         }
@@ -995,7 +997,7 @@ public class XAPDisAsm {
                         opcodeHoldingBay.clear();
                         baseAddressLastOpcode++;
                     }
-                    if(EntryPoint.verbose)System.out.println("VALUE");
+                    l.trace("VALUE");
                     //opcodeHoldingBay.add(word);
                 }
 

+ 2 - 2
SenaBitWiggler/src/main/resources/log4j2.xml

@@ -10,7 +10,7 @@
         </Console>
         
         
-        <RollingFile name="logfile" fileName="izpl.log" filePattern="izpl-%i.log">
+        <RollingFile name="logfile" fileName="senabitwiggler.log" filePattern="senabitwiggler-%i.log">
         <Policies>
             <OnStartupTriggeringPolicy />
             </Policies>
@@ -18,7 +18,7 @@
             <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %l - %msg%n"/>
         </RollingFile>   
 
-        <RollingFile name="logfileExternal" fileName="izpl.log" filePattern="izpl-%i.log">
+        <RollingFile name="logfileExternal" fileName="senabitwiggler.log" filePattern="senabitwiggler-%i.log">
         <Policies>
             <OnStartupTriggeringPolicy />
             </Policies>