/** * KKMulticopterFlashTool, a avrdude GUI for flashing KK boards and other * equipment. * Copyright (C) 2011 Christian Moll * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package de.lazyzero.kkMulticopterFlashTool.utils; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.text.DecimalFormat; import java.util.Enumeration; import java.util.Formatter; import java.util.HashMap; import java.util.Iterator; import java.util.Locale; import java.util.Vector; import java.util.logging.Level; import java.util.logging.Logger; //import org.json.simple.JSONObject; import de.lazyzero.kkMulticopterFlashTool.KKMulticopterFlashTool; public class Firmware { public static final int POT = 1; public static final int LCD = 2; public static final int PIEZO = 4; public static final int MEMS = 8; public static final int ACC = 16; public static final int CPPM = 32; public static final int LVA = 64; public static final int TARGET_KK = 0; public static final int TARGET_ESC = 1; public static final int TARGET_OPENAERO = 3; public static final int TARGET_CLOSD = 4; public static final int TARGET_RX3S = 5; private File file; private File eepromFile; private String version; private String author; private String name; private String controller; private String additionalOptions; private URL url; private String md5Calculated; private String md5; private String server; private URL zipURL; private URL commenturl; private String svnUrl; private String svnName; private int features; private int target = 0; private String versionName; private Logger logger = KKMulticopterFlashTool.getLogger(); private String fileName; private URL eepromUrl; private URL eepromZipUrl; private String svnEEpromUrl; private String svnEEpromName; private String eepromMD5; private String eepromMD5Calculated; private boolean isDeprecated = false; public Firmware(){} public Firmware(File firmwareFile) { this.file = firmwareFile; try { System.out.println(this.getFile().getAbsolutePath()); } catch (FileCorruptException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public Firmware(URL firmwareURL) throws NullPointerException{ if (firmwareURL!=null){ this.url = firmwareURL; } } public URL getFileURL() { return url; } public URL getZipURL() { return zipURL; } public File getFile() throws FileCorruptException{ if (KKMulticopterFlashTool.isOfflineMode()) { if (zipURL != null) { String filename = null; String tmpdir = null; String urlPath = url.getPath(); filename = urlPath.substring(urlPath.lastIndexOf("/")+1); System.out.println("Download file: "+filename); tmpdir = KKMulticopterFlashTool.getTempFolder(); File tmpFile = new File(tmpdir + filename); File fExtract = new File(url.toString().substring(7).trim()); this.file = Zip.unzipFile(tmpFile, fExtract); this.md5Calculated = MD5.getMD5(file); } else if (url != null) { String filename = null; String tmpdir = null; String urlPath = url.getPath(); filename = urlPath.substring(urlPath.lastIndexOf("/")+1); System.out.println("Load file from temp folder: "+filename); tmpdir = KKMulticopterFlashTool.getTempFolder(); this.file = new File(tmpdir + filename); this.md5Calculated = MD5.getMD5(file); System.out.println(md5Calculated); } else if (eepromZipUrl != null) { String filename = null; String tmpdir = null; //extract file name of eeprom file to know which file has to be extracted String urlPath = eepromUrl.getPath(); filename = urlPath.substring(urlPath.lastIndexOf("/")+1); System.out.println("Download file: "+filename); tmpdir = KKMulticopterFlashTool.getTempFolder(); File tmpFile = new File(tmpdir + filename); File fExtract = new File(url.toString().substring(7).trim()); this.eepromFile = Zip.unzipFile(tmpFile, fExtract); this.eepromMD5Calculated = MD5.getMD5(eepromFile); } else if (eepromUrl != null) { String filename = null; String tmpdir = null; String urlPath = eepromUrl.getPath(); filename = urlPath.substring(urlPath.lastIndexOf("/")+1); System.out.println("Load file from temp folder: "+filename); tmpdir = KKMulticopterFlashTool.getTempFolder(); this.eepromFile = new File(tmpdir + filename); this.eepromMD5Calculated = MD5.getMD5(eepromFile); System.out.println(eepromMD5Calculated); } } else { // this condition is for downloading the files if (zipURL != null) { File f = this.downloadFile(zipURL); File fExtract = new File(url.toString().substring(7).trim()); this.file = Zip.unzipFile(f, fExtract); this.md5Calculated = MD5.getMD5(file); } else if (svnUrl != null) { System.out.println("debug svn: " + svnUrl.toString()); try { SVN svn = new SVN(svnUrl.toString(), svnName); this.file = svn.getFile(); this.md5 = svn.getFileMD5(); this.md5Calculated = MD5.getMD5(file); logger.log(Level.INFO, "MD5 of SVN: " + md5 + " MD5 calculated from file: " + md5Calculated); } catch (Exception e) { logger.log(Level.SEVERE, "Problem during SVN action"); e.printStackTrace(); throw new FileCorruptException(); } } else if (url != null) { this.file=downloadFirmware(url); this.md5Calculated = MD5.getMD5(file); System.out.println(md5Calculated); } else if (eepromZipUrl != null) { File f = this.downloadFile(eepromZipUrl); File fExtract = new File(eepromUrl.toString().substring(7).trim()); this.eepromFile = Zip.unzipFile(f, fExtract); this.eepromMD5Calculated = MD5.getMD5(eepromFile); } else if (svnEEpromUrl != null) { System.out.println("debug svn: " + svnEEpromUrl.toString()); try { SVN svn = new SVN(svnEEpromUrl.toString(), svnEEpromName); this.eepromFile = svn.getFile(); this.eepromMD5 = svn.getFileMD5(); this.eepromMD5Calculated = MD5.getMD5(eepromFile); logger.log(Level.INFO, "MD5 of SVN: " + eepromMD5 + " MD5 calculated from EEPROM file: " + eepromMD5Calculated); } catch (Exception e) { logger.log(Level.SEVERE, "Problem during SVN action"); e.printStackTrace(); throw new FileCorruptException(); } } else if (eepromUrl != null) { this.eepromFile=downloadFirmware(eepromUrl); this.eepromMD5Calculated = MD5.getMD5(eepromFile); System.out.println(eepromMD5Calculated); } } //check the md5 if(null != md5 && !md5.equals("")) { logger.log(Level.INFO, "check MD5"); logger.log(Level.INFO, "MD5: " + md5 + " MD5 calculated from file: " + md5Calculated); if (!md5.equals(md5Calculated)){ logger.log(Level.SEVERE, "The file is corrupted."); throw new FileCorruptException(); } else { logger.log(Level.INFO, "File is okay."); } } else { logger.log(Level.INFO, "check MD5: no MD5 available. Check aborted."); } if (null != eepromMD5 && !eepromMD5.equals("")) { logger.log(Level.INFO, "check EEPROM MD5"); if (!eepromMD5.equals(eepromMD5Calculated)){ logger.log(Level.SEVERE, "The EEPROM file is corrupted."); throw new FileCorruptException(); } else { logger.log(Level.INFO, "EEPROM File is okay."); } } else { logger.log(Level.INFO, "check EEPROM MD5: no MD5 available. Check aborted."); } return file; } private File downloadFile(URL url){ String filename = null; String tmpdir = null; boolean reload = false; String urlPath = url.getPath(); filename = urlPath.substring(urlPath.lastIndexOf("/")+1).trim(); System.out.println("Download file: "+filename); tmpdir = KKMulticopterFlashTool.getTempFolder(); filename = tmpdir + filename; File tmpFile = new File(filename); if (filename.endsWith("tgy-daily.zip")) { reload = true; System.out.println("reload file: " + tmpFile.getName()); } if ((new File(tmpdir)).mkdir()) System.out.println("tmpdir created"); if (!tmpFile.exists() || reload) { try { BufferedInputStream in = new BufferedInputStream(url.openStream()); FileOutputStream fos = new FileOutputStream(tmpFile); BufferedOutputStream bout = new BufferedOutputStream(fos,1024); byte[] data = new byte[1024]; int x=0; while((x=in.read(data,0,1024))>=0) { bout.write(data,0,x); } bout.close(); in.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { System.out.println("skip download. File already loaded."); } System.out.println("Download finished: " + filename); return tmpFile; } private File downloadFirmware(URL firmwareURL){ String filename, tmpdir; String urlPath = firmwareURL.getPath(); filename = urlPath.substring(urlPath.lastIndexOf("/")+1); System.out.println("Download file: "+filename); tmpdir = KKMulticopterFlashTool.getTempFolder(); filename = tmpdir+filename; File tmpFile = new File(filename); if ((new File(tmpdir)).mkdir()) System.out.println("tmpdir created"); if (!tmpFile.exists()){ try { BufferedInputStream in = new BufferedInputStream(firmwareURL.openStream()); FileOutputStream fos = new FileOutputStream(tmpFile); BufferedOutputStream bout = new BufferedOutputStream(fos,1024); byte[] data = new byte[1024]; int x=0; while((x=in.read(data,0,1024))>=0) { bout.write(data,0,x); } bout.close(); in.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { System.out.println("skip download. File already loaded."); } System.out.println("Download finished: " + filename); return tmpFile; } public String toString() { return name + " ( V" + version + " [" + controller + "]" + " " + author + " )"; } public String toStringSorting() { //return name+version+author; //old if (target == TARGET_ESC) return name+version+author; StringBuilder sortableVersion = new StringBuilder(); String[] v = version.split("."); for (String part : v) { new Formatter(sortableVersion, Locale.US).format("00000000000000000000000000", part); } return author+name+sortableVersion; } public String toHTMLString() { return "<html>" + name + " (V" + version + " [" + controller + "])" + "<br>" + author ; // return "<html>" + name + " V" + version + " by " + author + (server.equals("")?"":("<br>" + server)) ; } public String getController() { return controller; } public URL getCommentURL() { return commenturl; } public boolean hasCommentURL() { System.out.println(commenturl); return (null != commenturl); } /** * @param version the version to set */ public void setVersion(String version) { this.version = version; } /** * @param author the author to set */ public void setAuthor(String author) { this.author = author; } /** * @param name the name to set */ public void setName(String name) { this.name = name; } public String getName() { return name; } /** * @param controller the controller to set */ public void setController(String controller) { this.controller = controller; } public void setMD5(String md5) { this.md5 = md5; } public String getMD5() { return this.md5; } public void setZipURL(URL zipurl) { this.zipURL = zipurl; } public void setCommentURL(URL commenturl) { this.commenturl = commenturl; } public static void main(String[] args) { Firmware f = null; try { f = new Firmware(); File ff = f.downloadFirmware(new URL("http://www.kkmulticopter.kr/multicopter/firmware/XXcontrol_KR_DualCopter_v1_5.hex")); MD5.getMD5(ff); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } // try { // f = new Firmware(new URL("http://www.lazyzero.de/_media/firmware.hex")); // f.setAuthor("ich"); // f.setController("m48"); // f.setName("Quad"); // f.setVersion("0.3"); // } catch (NullPointerException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } catch (MalformedURLException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } // f.getFile(); //f.downloadFirmware(f.url); } public static Vector<Firmware> getOfflineAvailableFirmwares(Vector<Firmware> inputFirmwares) { Vector<Firmware> firmwares = new Vector<Firmware>(); String tmpFolder = KKMulticopterFlashTool.getTempFolder(); for (Firmware firmware : inputFirmwares) { if (firmware.zipURL != null) { String urlPath = firmware.zipURL.getPath(); String filename = urlPath.substring(urlPath.lastIndexOf("/")+1); if (new File(tmpFolder+filename).exists()) { firmwares.add(firmware); } } else if (firmware.url != null) { String urlPath = firmware.url.getPath(); String filename = urlPath.substring(urlPath.lastIndexOf("/")+1); if (new File(tmpFolder+filename).exists()) { firmwares.add(firmware); } } } return firmwares; } public static Vector<String> getCategories(Vector<Firmware> firmwares) { Vector<String>firmwareTyps = new Vector<String>(); Enumeration<Firmware> en = firmwares.elements(); while (en.hasMoreElements()) { Firmware firmware = (Firmware) en.nextElement(); if (!firmwareTyps.contains(firmware.getName())) { firmwareTyps.add(firmware.getName()); } } return firmwareTyps; } public static HashMap<String,Boolean> getCategoriesBooleanHashMap(Vector<Firmware> firmwares) { HashMap<String, Boolean>firmwareTyps = new HashMap<String,Boolean>(); Enumeration<Firmware> en = firmwares.elements(); while (en.hasMoreElements()) { Firmware firmware = (Firmware) en.nextElement(); if (!firmwareTyps.containsKey(firmware.getName())) { firmwareTyps.put(firmware.getName(), false); } } return firmwareTyps; } public static Vector<Firmware> filter(String category, Vector<Firmware> firmwares) { Vector<Firmware> f = new Vector<Firmware>(); for (Iterator<Firmware> iterator = firmwares.iterator(); iterator.hasNext();) { Firmware firmware = iterator.next(); if (category.toString().equals(firmware.getName())) { f.add(firmware); } } return f; } public void setAdditionalOptions(String additionalOptions) { this.additionalOptions = additionalOptions; } public String getAdditionalOptions() { return this.additionalOptions; } public void setFeatures(int features) { this.features = features; } public int getFeatures() { return this.features; } public String getServer() { return server; } public void setServer(String server) { this.server = server; } public void setTargetPlatform(int target) { this.target = target; } public int getTarget() { return target; } public String getAuthor() { return author; } public String getVersion() { return version; } public void setVersionName(String versionName) { this.versionName = versionName; } public String getVersionName() { return this.versionName; } public String getSVN() { return this.svnUrl; } public void setSVN(String svnUrl) { this.svnUrl = svnUrl; } public String getSVNname() { return this.svnName; } public void setSVNname(String svnName) { this.svnName = svnName; } public String getFileName() { return fileName ; } public void setFileName(String fileName) { this.fileName = fileName.substring(fileName.lastIndexOf('/')+1); } public void setEEpromURL(URL eepromUrl) { this.eepromUrl = eepromUrl; } public void setEEpromZipURL(URL eepromZipUrl) { this.eepromZipUrl = eepromZipUrl; } public void setEEpromSVN(String svnEEpromUrl) { this.svnEEpromUrl = svnEEpromUrl; } public void setEEpromMD5(String md5) { this.eepromMD5 = md5; } public void setEEpromSVNname(String svnEEpromName) { this.svnEEpromName = svnEEpromName; } public void setDeprecated(boolean isDeprecated) { this.isDeprecated = isDeprecated; } public boolean isDeprecated() { return isDeprecated; } // public String toJSON() { // JSONObject obj = new JSONObject(); // obj.put("author", author); // obj.put("controller", controller); // return obj.toJSONString(); // } }