public SApplication101(kXMLElement anode, LayerThread alower) { super("Slave Application 101", 1); this.initalized.set(false); // my lower layer is alower this.lower = alower; // lower Thread - i am the upper one for you this.lower.upper = this; // save config this.node = anode; // name this.name = node.getProperty("name", "unbekannt"); protocol = new ProtocolConfig(anode); // the SAppManager builds my personal upper layer and sents me data if necessary mgr = new SAppManager101(this, protocol.casdu, protocol.polling); mgr.name = name; // ********************************************************************** // Analyzing Configuration // ********************************************************************** /* * example config is * <MappingList> <Mapping> <Key vsq="1" caa="513" id="13"/> <Value pie="0" ioa="8970" db="4001" pval="0"/> </Mapping> <Mapping> <Key vsq="1" caa="513" id="45"/> <Value pie="0" ioa="8970" db="5000" pval="0"/> </Mapping> </MappingList> */ // 1st of all we need a mapping list try { kXMLElement child = anode.getChild(0); if (child.getTagName().equals("MappingList")) { mgr.map = Mapping(child, mgr); } } catch (Exception e) { IEC60870App.err("Slave104 Konfiguration fehlt Tag MappingList...", "-", 1); // no service available; return; } manager.put(mgr.casdu, mgr); // set the ASDU Reader/Writer instances with default values due to 101 specification // cotsize cause of transmission size (how many bytes??) // casdusize common address size (how many bytes??) // ioasize information object address size (how many bytes??) this.reader = new SAsduReader101(protocol.cotsize, protocol.casdusize, protocol.ioasize); this.writer = new SAsduWriter101(protocol.cotsize, protocol.casdusize, protocol.ioasize); }
@Override protected void lowerEvent(Object object) throws IEC608705Exception { { short[] raw_asdu = (short[]) object; // Anlayse bzgl. GA und Confirmations UserData data = null; Asdu asdu = null; try { data = analyze_asdu(raw_asdu); asdu = reader.build(data); } catch (Exception e) { String msg = ""; if (raw_asdu != null) { for (int ii = 0; ii < raw_asdu.length; ii++) { msg = msg + "[" + Short.toString(raw_asdu[ii]) + "] "; } } else { msg = "null"; } IEC60870App.err( "Fehlerhafte Asdu, verwerfe Paket der Länge " + raw_asdu.length + " ..." + msg, name, 1); return; } // Wenn ASDU==null, dann ist sie nicht ausgwertet worden -> Fehler. if (asdu == null) { if (raw_asdu != null) { String msg = ""; for (int ii = 0; ii < raw_asdu.length; ii++) { msg = msg + " " + Short.toString(raw_asdu[ii]); } IEC60870App.err("Asdu nicht auswertbar durch Asdureader: " + msg, name, 1); } return; } SAppManager101 mngr = null; // should we be interested to analyse the data?? // if asdu == 65535, then global procedure call if (manager.containsKey(new Integer(asdu.caa)) || asdu.caa == 65535) { switch (asdu.cot) { /* * Übertragungsursachen, die eine Rückantwort verlangen * * 6 - Aktivierung, muss mit 7 beantwortet werden * 8 - Abbruch der Aktivierung, muss mit 9 beantwortet werden */ case 6: case 8: // Manager schreibt Rückantwort if (asdu.caa != 65535) { mngr = (SAppManager101) manager.get(new Integer(protocol.casdu)); mngr.evaluate(asdu); } else { for (Enumeration e = manager.elements(); e.hasMoreElements(); ) { mngr = (SAppManager101) e.nextElement(); mngr.evaluate(asdu, 1); } } break; /* * Übertragungsursachen, die lediglich bestätigt werden müssen * * 3 - spontan * 5 - abgefragt * */ case 3: case 5: case 7: case 9: // case 10: case 44: case 45: case 46: case 47: // ohne Modifikation zurückschreiben write(object); break; } } else { // Modifikation des Objektes cot=46 für unbekannte Stationsadresse modify_cot(raw_asdu, 46); write(raw_asdu); } } }