Commit 3efd3a05 authored by Claes Sjofors's avatar Claes Sjofors

WebSocketServer added

parent e027861c
......@@ -51,6 +51,7 @@ JNIEXPORT jint JNICALL Java_jpwr_rt_Errh_init
name = (*env)->GetStringUTFChars( env, jname, 0);
cstr = (char *)name;
printf( "Init errh %s %d", cstr, anix);
sts = errh_Init( cstr, anix);
(*env)->ReleaseStringUTFChars( env, jname, cstr);
......
......@@ -493,7 +493,7 @@ JNIEXPORT jobjectArray JNICALL Java_jpwr_rt_Gdh_getObjectRefInfoStringArray
JNIEXPORT jobject JNICALL Java_jpwr_rt_Gdh_refObjectInfo
(JNIEnv *env, jclass obj, jstring name)
{
int sts;
int sts = GDH__SUCCESS;
const char *str;
char *cstr;
void *attr_p;
......@@ -557,11 +557,11 @@ JNIEXPORT jobject JNICALL Java_jpwr_rt_Gdh_refObjectInfo
}
else
{
typeid = pwr_eType_Boolean;
size = sizeof(pwr_tBoolean);
elements = 1;
sts = gdh_GetAttributeCharacteristics( cstr, &typeid, (pwr_tUInt32 *)&size, 0,
(pwr_tUInt32 *)&elements);
}
if ( ODD(sts))
sts = gdh_RefObjectInfo( cstr, &attr_p, &subid, size);
if ( ODD(sts))
......
......@@ -80,6 +80,9 @@ JNIEXPORT jobject JNICALL Java_jpwr_rt_RtSecurity_checkUser
aref = cdh_ObjidToAref( oid);
sts = gdh_GetObjectInfoAttrref( &aref, &sec, sizeof(sec));
if ( ODD(sts)){
if ( strcmp( cuser, "") == 0)
priv = sec.DefaultWebPriv;
else
sts = user_CheckUser( sec.WebSystemGroup, cuser, cpassword, &priv);
}
}
......
......@@ -69,16 +69,16 @@ public class GlowConPoint extends GlowArrayElem {
case Glow.eSave_ConPoint:
break;
case Glow.eSave_ConPoint_number:
number =Integer.valueOf(token.nextToken());
number = Integer.valueOf(token.nextToken());
break;
case Glow.eSave_ConPoint_direction:
number =Integer.valueOf(token.nextToken());
direction = Integer.valueOf(token.nextToken());
break;
case Glow.eSave_ConPoint_p:
p.open(reader);
break;
case Glow.eSave_ConPoint_trace_attr_type:
trace_attr_type =Integer.valueOf(token.nextToken());
trace_attr_type = Integer.valueOf(token.nextToken());
break;
case Glow.eSave_ConPoint_trace_attribute:
if ( token.hasMoreTokens())
......
......@@ -56,6 +56,7 @@ public class CdhrObjAttr implements Serializable
public GdhrRefObjectInfo refObj;
public String name;
public String fullName = null;
public String className = null;
public int type;
public int size;
public int flags;
......
......@@ -42,6 +42,7 @@ package jpwr.rt;
public class Errh {
public static final int eAnix_webmon = 14;
public static final int eAnix_webmonmh = 15;
public static final int eAnix_websocketserver = 28;
public static final int PWR__SRVSTARTUP = 134512720;
public static final int PWR__SRUN = 134512731;
......
......@@ -200,8 +200,7 @@ public class Gdh {
}
//public Vector getAllClassAttributes( int classid, PwrtObjid objid_obj )
public Vector<CdhrObjAttr> getAllClassAttributes( int classid, PwrtObjid objid_obj )
{
public Vector<CdhrObjAttr> getAllClassAttributes( int classid, PwrtObjid objid_obj) {
//System.out.println("getAllClassAttributes" + classid + " " + objid_obj.oix + " " + objid_obj.vid);
String name = this.objidToName(objid_obj, Cdh.mName_pathStrict).str;
......@@ -212,26 +211,27 @@ public class Gdh {
Vector<CdhrObjAttr> v = new Vector<CdhrObjAttr>();
//Vector v = new Vector();
for(int i = 0;i<gdhrsAttrDefArr.length;i++)
{
if(gdhrsAttrDefArr[i] == null)
for( int i = 0;i<gdhrsAttrDefArr.length;i++) {
if ( gdhrsAttrDefArr[i] == null)
break;
//System.out.println("getAllClassAttributesFor:" + i + gdhrsAttrDefArr[i].attrName);
while(gdhrsAttrDefArr[i].attrName.startsWith("Super."))
while ( gdhrsAttrDefArr[i].attrName.startsWith("Super."))
gdhrsAttrDefArr[i].attrName = gdhrsAttrDefArr[i].attrName.substring(6);
CdhrObjAttr oa;
if((gdhrsAttrDefArr[i].info.Flags & Pwr.mAdef_class) > 0)
{
if ( (gdhrsAttrDefArr[i].info.Flags & Pwr.mAdef_class) > 0) {
oa = new CdhrObjAttr(this.nameToObjid(name + "." + gdhrsAttrDefArr[i].attrName).objid,
gdhrsAttrDefArr[i].attrName,
gdhrsAttrDefArr[i].typeRef,
gdhrsAttrDefArr[i].info.Size,
gdhrsAttrDefArr[i].info.Flags,
gdhrsAttrDefArr[i].info.Elements);
CdhrObjid classObj = this.classIdToObjid( gdhrsAttrDefArr[i].info.Type);
if ( classObj.oddSts())
oa.className = this.objidToName(classObj.objid, Cdh.mName_object).str;
}
else
{
else {
//System.out.println("getAllClassAttr:" + name + "." + gdhrsAttrDefArr[i].attrName);
oa = new CdhrObjAttr(this.nameToObjid(name + "." + gdhrsAttrDefArr[i].attrName).objid,
gdhrsAttrDefArr[i].attrName,
......@@ -242,6 +242,7 @@ public class Gdh {
}
v.add(oa);
}
return v;
}
......
/*
* Proview Open Source Process Control.
* Copyright (C) 2005-2017 SSAB EMEA AB.
*
* This file is part of Proview.
*
* 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 2 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 Proview. If not, see <http://www.gnu.org/licenses/>
*
* Linking Proview statically or dynamically with other modules is
* making a combined work based on Proview. Thus, the terms and
* conditions of the GNU General Public License cover the whole
* combination.
*
* In addition, as a special exception, the copyright holders of
* Proview give you permission to, from the build function in the
* Proview Configurator, combine Proview with modules generated by the
* Proview PLC Editor to a PLC program, regardless of the license
* terms of these modules. You may copy and distribute the resulting
* combined work under the terms of your choice, provided that every
* copy of the combined work is accompanied by a complete copy of
* the source code of Proview (the version used to produce the
* combined work), being distributed under the terms of the GNU
* General Public License plus this exception.
*/
package jpwr.rt;
import java.net.*;
import java.io.*;
import java.nio.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.bind.DatatypeConverter;
import java.security.MessageDigest;
//for test
import java.sql.Timestamp;
import java.util.Date;
import java.util.Timer;
import javax.swing.*;
//end for test
/**
Server process for communication with web and app clients.
@author claes, Jonas
*/
public class GdhWebSocketServer
{
public final static int SET_OBJECT_INFO_BOOLEAN = 1;
public final static int SET_OBJECT_INFO_FLOAT = 2;
public final static int SET_OBJECT_INFO_INT = 3;
public final static int SET_OBJECT_INFO_STRING = 4;
public final static int GET_OBJECT_INFO_BOOLEAN = 5;
public final static int GET_OBJECT_INFO_FLOAT = 6;
public final static int GET_OBJECT_INFO_INT = 7;
public final static int GET_OBJECT_INFO_STRING = 8;
public final static int TOGGLE_OBJECT_INFO = 9;
public final static int REF_OBJECT_INFO = 10;
public final static int GET_OBJECT_REF_INFO_BOOLEAN = 11;
public final static int GET_OBJECT_REF_INFO_FLOAT = 12;
public final static int GET_OBJECT_REF_INFO_INT = 13;
public final static int GET_OBJECT_REF_INFO_STRING = 14;
public final static int UNREF_OBJECT_INFO = 15;
public final static int NAME_TO_OBJID = 16;
public final static int OBJID_TO_NAME = 17;
public final static int GET_ROOT_LIST = 18;
public final static int GET_NEXT_OBJECT = 19;
public final static int GET_CHILD = 20;
public final static int GET_NEXT_SIBLING = 21;
public final static int GET_OBJECT_CLASS = 22;
public final static int GET_CLASS_LIST = 23;
public final static int CLASS_ID_TO_OBJID = 24;
public final static int GET_OBJECT_REF_INFO_ALL = 25;
public final static int REF_OBJECT_INFO_LIST = 26;
public final static int POLL = 27;
public final static int STATISTICS = 28;
public final static int CHECK_USER = 29;
public final static int GET_NODE_OBJECT = 30;
public final static int LOG_STRING = 31;
public final static int UNREF_OBJECT_INFO_ALL = 32;
public final static int CREATE_INSTANCE_FILE = 33;
public final static int GET_ATTRIBUTE_CHAR = 34;
public final static int GET_CLASS_ATTRIBUTE = 35;
public final static int GET_ALL_CLASS_ATTRIBUTES = 36;
public final static int GET_ALL_SIBLINGS = 37;
public final static int GET_ALL_XTT_SIBLINGS = 38;
public final static int GET_ALL_XTT_CHILDREN = 39;
public final static int REF_OBJECT_INFO_VECTOR = 40;
public final static int GET_SUBSCRIPTIONS = 41;
public final static int CRR_SIGNAL = 42;
public final static int CRR_OBJECT = 43;
public final static int GET_PARENT = 44;
public final static int GET_OBJECT_INFO_OBJID = 45;
public final static int GET_OBJECT_REF_INFO_BOOLEAN_ARRAY = 46;
public final static int GET_OBJECT_REF_INFO_FLOAT_ARRAY = 47;
public final static int GET_OBJECT_REF_INFO_INT_ARRAY = 48;
public final static int GET_OBJECT_REF_INFO_STRING_ARRAY = 49;
public final static int GET_MSG = 50;
public final static int GET_MSG_TEXT = 51;
public final static int NAME_TO_ATTRREF = 52;
public final static int ATTRREF_TO_NAME = 53;
public final static int GET_ATTRREF_TID = 54;
public final static int GET_SUPER_CLASS = 55;
public final static int GET_ALL_CLASS_ATTRIBUTES_STRING = 56;
public final static int GET_OBJECT_INFO_FLOAT_ARRAY = 57;
public final static int GET_OBJECT_INFO_INT_ARRAY = 58;
public final static int GET_CIRCBUFF_INFO = 59;
public final static int UPDATE_CIRCBUFF_INFO = 60;
public final static int GET_ATTRIBUTE_FLAGS = 61;
public final static int CLASSNAME_TO_ID = 62;
public final static int GET_OBJECT = 63;
public final static int GET_OPWIND_MENU = 64;
public final static int GET_OBJECT_FROM_NAME = 65;
public final static int GET_OP_SELF = 1;
public final static int GET_OP_METHOD_PLC = 2;
public final static int GET_OP_METHOD_OBJECTGRAPH = 3;
public final static int PORT = 4448;
public final static int __IO_EXCEPTION = 2000;
public final static int __UNREFED = 0;
//static ArrayList<SubElement> subscriptions = new ArrayList<SubElement>();
static ArrayList subscriptions = new ArrayList();
static int subscriptionCount = 0;
static int threadCount = 0;
static int totalThreadCount = 0;
Gdh gdh;
Errh errh;
int maxConnections;
String currentConnectionsStr;
static boolean ignoreHandler = false;
static boolean log = false;
static boolean logRefInfoAll = false;
static boolean logStatistics = false;
static boolean debug = true;
static int lastIndexReffed = 0;
class WebButton {
public static final int GRAPH = 0;
public static final int LINK = 1;
public int type;
public String text;
public String name;
public String url;
}
/**
* The main program for the GdhWebSocketServer class
*
* @param args The command line arguments
*/
public static void main(String[] args) {
System.out.println( "java.library.path = " + System.getProperty("java.library.path"));
for( int i = 0; i < args.length; i++) {
if( args[i].equals("-i")) {
ignoreHandler = true;
}
else if ( args[i].equals("-l")) {
log = true;
}
else if ( args[i].equals("-logRefInfoAll")) {
logRefInfoAll = true;
}
else if ( args[i].equals("-s")) {
logStatistics = true;
}
}
if ( log) {
System.out.println("WebSocketServer starting ver 0.1");
}
if ( logRefInfoAll) {
System.out.println("WebSocketServer starting ver 0.1 -logRefInfoAll");
}
GdhWebSocketServer gdhServer = new GdhWebSocketServer();
gdhServer.openServerSocket();
gdhServer.errh.setStatus( Errh.PWR__SRVTERM);
System.out.println("WebSocketServer exiting");
System.exit(0);
}
public GdhWebSocketServer() {
}
/**
Gets the handlerObject attribute of the WebSocketServer object
@return The handlerObject value
*/
private int getHandlerObject() {
if ( ignoreHandler) {
maxConnections = 50;
return 1;
}
CdhrObjid cdhrObjid;
CdhrString cdhrString;
CdhrInt cdhrInt;
cdhrObjid = gdh.getClassList( Pwrb.cClass_WebSocketServer);
if(cdhrObjid.evenSts()) {
errh.info("No WebSocketServer is configured, WebSocketServer terminating");
return cdhrObjid.getSts();
}
cdhrString = gdh.objidToName(cdhrObjid.objid, Cdh.mName_volumeStrict);
if( cdhrString.evenSts())
return cdhrString.getSts();
String attr = cdhrString.str + ".MaxConnections";
cdhrInt = gdh.getObjectInfoInt(attr);
if(cdhrInt.evenSts())
return cdhrInt.getSts();
maxConnections = cdhrInt.value;
currentConnectionsStr = cdhrString.str + ".CurrentConnections";
setCurrentConnections(threadCount);
errh.info("WebSocketServer started, MaxConnections: " + maxConnections);
return 1;
}
/**
Sets the currentConnections attribute of the WebSockerServer object
@param connections The new currentConnections value
*/
private void setCurrentConnections(int connections) {
PwrtStatus sts;
if(!ignoreHandler)
sts = gdh.setObjectInfo(currentConnectionsStr, connections);
}
/**
Open a server socket and wait for connect requests.
*/
public void openServerSocket() {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(PORT);
serverSocket.setSoTimeout(1000);
}
catch(IOException e) {
errh = new Errh("WebSocketServer", Errh.eAnix_websocketserver);
errh.fatal("Open socket port " + PORT + " " + e.getMessage());
return;
}
if ( debug)
System.out.println( "Server started on port 127.0.0.1:" + PORT);
gdh = new Gdh((GdhApplIfc)null);
errh = new Errh("WebSocketServer", Errh.eAnix_websocketserver);
errh.setStatus( Errh.PWR__SRVSTARTUP);
int sts = getHandlerObject();
if(sts % 2 == 0) {
errh.setStatus( 0);
System.exit(0);
}
errh.setStatus( Errh.PWR__SRUN);
Qcom qcom = new Qcom();
QcomrCreateQ qque = qcom.createIniEventQ("WebSocketServer");
if( qque.evenSts()) {
errh.fatal("WebSocketServer couldn create EventQue");
return;
}
QcomrGetIniEvent qrGetIniEv;
while(true) {
Socket cliSocket = null;
try {
// Wait for accept
cliSocket = serverSocket.accept();
}
catch(InterruptedIOException e) {
qrGetIniEv = qcom.getIniEvent(qque.qix, qque.nid, 0);
if(qrGetIniEv.timeout)
continue;
else if(qrGetIniEv.terminate) {
System.out.println("WebSocketServer received killmess from QCom");
return;
}
else {
//Do nothing for the moment
//But in the future we should reinitialize if swap
continue;
}
}
catch(IOException e) {
errh.error("Accept failed.");
continue;
}
if(threadCount <= maxConnections) {
// Create a new thread
threadCount++;
totalThreadCount++;
setCurrentConnections(threadCount);
GdhThread gdhThread = new GdhThread(cliSocket, totalThreadCount, maxConnections);
}
else {
errh.warning("Connection dismissed, max number of connections exceeded");
try {
cliSocket.close();
}
catch(IOException e2) {
errh.error("Connection close failed");
}
}
}
}
private class GdhThread extends Thread {
Socket clientSocket;
public Vector<Sub> thSub = new Vector<Sub>();
// public Vector thSub = new Vector();
int maxConnections;
int threadNumber;
java.util.Timer timer;
OutputStream out = null;
public GdhThread(Socket clientSocket, int threadNumber, int maxConnections) {
/************ In case of debugging this might be useful
System.out.println("threadnumber : " + threadNumber + "maxconn " + maxConnections);
try{
System.out.println("HostName :" + clientSocket.getInetAddress().getHostName() +
"Delay : " + clientSocket.getTcpNoDelay());
}
catch(SocketException exc){}
************************************/
this.threadNumber = threadNumber;
this.clientSocket = clientSocket;
this.maxConnections = maxConnections;
start();
}
class SendSub extends TimerTask {
public void run() {
System.out.println( "SendSub");
int id = 5678;
int sts = 123;
int size = 0;
int cnt = 0;
for ( int i = 0; i < thSub.size(); i++) {
Sub sub = (Sub)thSub.elementAt(i);
switch( sub.typeId) {
case Pwr.eType_Boolean:
size += 8 + 1;
cnt++;
break;
case Pwr.eType_Float32:
size += 8 + 4;
cnt++;
break;
default:
continue;
}
}
byte[] msg = new byte[15 + size];
msg[0] = (byte)130;
msg[1] = (byte)(15 + size);
msg[2] = GET_OBJECT_REF_INFO_ALL;
msg[3] = (byte)(id >> 24);
msg[4] = (byte)((id >> 16) & 0xFF);
msg[5] = (byte)((id >> 8) & 0xFF);
msg[6] = (byte)(id & 0xFF);
msg[7] = (byte)(sts >> 24);
msg[8] = (byte)((sts >> 16) & 0xFF);
msg[9] = (byte)((sts >> 8) & 0xFF);
msg[10] = (byte)(sts & 0xFF);
int j = 11;
ByteBuffer bb = ByteBuffer.wrap( msg);
bb.putInt( j, cnt);
j += 4;
for ( int i = 0; i < thSub.size(); i++) {
Sub sub = (Sub)thSub.elementAt(i);
if ( sub == null)
continue;
bb.putInt( j, sub.subscriptionsIndex);
j += 4;
switch( sub.typeId) {
case Pwr.eType_Boolean:
bb.putInt( j, 1);
j += 4;
boolean value = gdh.getObjectRefInfoBoolean(sub.id);
System.out.println( i + " Value: " + value + " Type " + sub.typeId + " " + (15+size) + " " + j);
bb.put( j, value ? (byte)1 : (byte)0);
j += 1;
break;
case Pwr.eType_Float32:
break;
default:
continue;
}
}
if ( debug)
System.out.println( "Sending: " + msg);
try {
out.write( msg);
out.flush();
}
catch(IOException e) {
System.out.println("SendSub failed" + e.toString());
}
}
}
/**
Main processing method for the GdhThread object
*/
public void run() {
if(log) {
errh.info("New connection (" + threadNumber + ")");
}
// timer = new java.util.Timer();
// timer.scheduleAtFixedRate( new SendSub(), 1000, 5000);
Sub sub;
Vector subCopy;
BufferedInputStream in = null;
// Handshake
try {
InputStream instream = clientSocket.getInputStream();
out = clientSocket.getOutputStream();
String data = new Scanner( instream, "UTF-8").useDelimiter("\\r\\n\\r\\n").next();
Matcher get = Pattern.compile("^GET").matcher(data);
if ( get.find()) {
System.out.println("Match GET");
Matcher match = Pattern.compile("Sec-WebSocket-Key: (.*)").matcher(data);
match.find();
byte[] response = ("HTTP/1.1 101 Switching Protocols\r\n"
+ "Connection: Upgrade\r\n"
+ "Upgrade: websocket\r\n"
+ "Sec-WebSocket-Accept: "
+ DatatypeConverter.printBase64Binary(
MessageDigest
.getInstance("SHA-1")
.digest((match.group(1) + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11")
.getBytes("UTF-8")))
+ "\r\n\r\n")
.getBytes("UTF-8");
System.out.println("Sending " + response);
out.write(response, 0, response.length);
in = new BufferedInputStream(instream);
}
}
catch(IOException e) {
errh.error("DataStream failed");
threadCount--;
setCurrentConnections(threadCount);
return;
}
catch ( java.security.NoSuchAlgorithmException e) {
System.out.println("ServerSocket NoSuchAlgorithmException");
}
try {
while ( true) {
int c1 = in.read();
int opcode = c1 & 0xF;
int c2 = in.read();
int size = 0x7F & c2;
if ( size == 126) {
size = (in.read() << 8) + in.read();
}
else if ( size == 127) {
size = (in.read() << 24) + (in.read() << 16) + (in.read() << 8) + in.read();
}
if ( size < 0)
continue;
//System.out.println( "Received: " + c1 + " " + c2 + " " + size);
int[] key = new int[4];
key[0] = in.read();
key[1] = in.read();
key[2] = in.read();
key[3] = in.read();
//System.out.println( "Key : " + key[0] + " " + key[1] + " " + key[2] + " " + key[3]);
switch ( opcode) {
case 1:
case 2:
break;
case 9:
System.out.println( "Opcode 9, Ping");
return;
case 10:
System.out.println( "Opcode 10, Ping");
return;
case 8:
byte[] value = new byte[2];
for ( int i = 0; i < 2; i++) {
int c = in.read();
value[i] = (byte)(c ^ key[i & 0x3]);
}
int reason = ((value[1] & 0xFF) << 0) + ((value[0] & 0xFF) << 8);
System.out.println( "Opcode 8, Connection closed, reason: " + reason);
if ( timer != null)
timer.cancel();
return;
default:
System.out.println( "Unknown opcode: " + opcode);
}
byte[] value = new byte[size];
for ( int i = 0; i < size; i++) {
int c = in.read();
value[i] = (byte)(c ^ key[i & 0x3]);
}
int id = ((value[2] & 0xFF) << 0) + ((value[3] & 0xFF) << 8) + ((value[4] & 0xFF) << 16) + ((value[5] & 0xFF) << 24);
//System.out.println( "id: " + id);
switch ( value[0]) {
case GET_OBJECT_INFO_BOOLEAN:
try {
String attrName = new String( value, 6, size - 6);
CdhrBoolean ret = gdh.getObjectInfoBoolean(attrName);
int sts = ret.getSts();
if ( debug)
System.out.println( "getObjectInfo: " + id + " " + attrName + " sts: " + ret.getSts() + " value: " + ret.value);
byte[] msg = new byte[12];
msg[0] = (byte)130;
msg[1] = 10;
msg[2] = GET_OBJECT_INFO_BOOLEAN;
msg[3] = (byte)(id >> 24);
msg[4] = (byte)((id >> 16) & 0xFF);
msg[5] = (byte)((id >> 8) & 0xFF);
msg[6] = (byte)(id & 0xFF);
msg[7] = (byte)(sts >> 24);
msg[8] = (byte)((sts >> 16) & 0xFF);
msg[9] = (byte)((sts >> 8) & 0xFF);
msg[10] = (byte)(sts & 0xFF);
if ( ret.oddSts())
msg[11] = ret.value ? (byte) 1 : (byte) 0;
if ( debug)
System.out.println( "Sending: " + msg);
out.write( msg);
out.flush();
}
catch(IOException e) {
System.out.println("getObjectInfoBoolean: IO exception");
}
break;
case GET_OBJECT_INFO_INT:
try {
String attrName = new String( value, 6, size - 6);
CdhrInt ret = gdh.getObjectInfoInt(attrName);
int sts = ret.getSts();
if ( debug)
System.out.println( "getObjectInfo: " + id + " " + attrName + " sts: " + ret.getSts() + " value: " + ret.value);
byte[] msg = new byte[15];
msg[0] = (byte)130;
msg[1] = 13;
msg[2] = GET_OBJECT_INFO_INT;
msg[3] = (byte)(id >> 24);
msg[4] = (byte)((id >> 16) & 0xFF);
msg[5] = (byte)((id >> 8) & 0xFF);
msg[6] = (byte)(id & 0xFF);
msg[7] = (byte)(sts >> 24);
msg[8] = (byte)((sts >> 16) & 0xFF);
msg[9] = (byte)((sts >> 8) & 0xFF);
msg[10] = (byte)(sts & 0xFF);
if ( ret.oddSts()) {
msg[11] = (byte)(ret.value >> 24);
msg[12] = (byte)((ret.value >> 16) & 0xFF);
msg[13] = (byte)((ret.value >> 8) & 0xFF);
msg[14] = (byte)(ret.value & 0xFF);
}
if ( debug)
System.out.println( "Sending: " + msg);
out.write( msg);
out.flush();
}
catch(IOException e) {
System.out.println("getObjectInfoInt: IO exception");
}
break;
case GET_OBJECT_INFO_FLOAT:
try {
String attrName = new String( value, 6, size - 6);
CdhrFloat ret = gdh.getObjectInfoFloat(attrName);
int sts = ret.getSts();
if ( debug)
System.out.println( "getObjectInfo: " + id + " " + attrName + " sts: " + ret.getSts() + " value: " + ret.value);
byte[] msg = new byte[15];
msg[0] = (byte)130;
msg[1] = 13;
msg[2] = GET_OBJECT_INFO_FLOAT;
msg[3] = (byte)(id >> 24);
msg[4] = (byte)((id >> 16) & 0xFF);
msg[5] = (byte)((id >> 8) & 0xFF);
msg[6] = (byte)(id & 0xFF);
msg[7] = (byte)(sts >> 24);
msg[8] = (byte)((sts >> 16) & 0xFF);
msg[9] = (byte)((sts >> 8) & 0xFF);
msg[10] = (byte)(sts & 0xFF);
if ( ret.oddSts()) {
ByteBuffer bb = ByteBuffer.wrap( msg);
bb.putFloat( 11, ret.value);
}
if ( debug)
System.out.println( "Sending: " + msg);
out.write( msg);
out.flush();
}
catch(IOException e) {
System.out.println("getObjectInfoFloat: IO exception");
}
break;
case GET_OBJECT_INFO_FLOAT_ARRAY:
try {
int i = 6;
int asize = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8) + ((value[i+2] & 0xFF) << 16) + ((value[i+3] & 0xFF) << 24);
i += 4;
String attrName = new String( value, i, size - i);
CdhrFloatArray ret = gdh.getObjectInfoFloatArray(attrName, asize);
int sts = ret.getSts();
if ( debug)
System.out.println( "getObjectInfoFloatArray: " + id + " " + asize + " " + attrName + " sts: " + ret.getSts() + " value: " + ret.value);
byte[] msg = new byte[13 + asize *4];
msg[0] = (byte)130;
int j;
if ( asize * 4 + 13 < 125) {
msg = new byte[15 + asize * 4];
msg[0] = (byte)130;
msg[1] = (byte)(13 + asize * 4);
j = 2;
}
else {
msg = new byte[17 + asize * 4];
msg[0] = (byte)130;
msg[1] = (byte)126;
msg[2] = (byte)(((13 + asize * 4) >> 8) & 0xFF);
msg[3] = (byte)((13 + asize * 4) & 0xFF);
j = 4;
}
msg[j++] = GET_OBJECT_INFO_FLOAT_ARRAY;
msg[j++] = (byte)(id >> 24);
msg[j++] = (byte)((id >> 16) & 0xFF);
msg[j++] = (byte)((id >> 8) & 0xFF);
msg[j++] = (byte)(id & 0xFF);
msg[j++] = (byte)(sts >> 24);
msg[j++] = (byte)((sts >> 16) & 0xFF);
msg[j++] = (byte)((sts >> 8) & 0xFF);
msg[j++] = (byte)(sts & 0xFF);
if ( ret.oddSts()) {
msg[j++] = (byte)(asize >> 24);
msg[j++] = (byte)((asize >> 16) & 0xFF);
msg[j++] = (byte)((asize >> 8) & 0xFF);
msg[j++] = (byte)(asize & 0xFF);
ByteBuffer bb = ByteBuffer.wrap( msg);
for ( int k = 0; k < asize; k++) {
bb.putFloat( j, ret.value[k]);
j += 4;
}
}
if ( debug)
System.out.println( "Sending: " + msg);
out.write( msg);
out.flush();
}
catch(IOException e) {
System.out.println("getObjectInfoFloatArray: IO exception");
}
break;
case SET_OBJECT_INFO_BOOLEAN:
try {
int i = 6;
int val = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8) + ((value[i+2] & 0xFF) << 16) + ((value[i+3] & 0xFF) << 24);
boolean bvalue = ((val == 0) ? false : true);
i += 4;
int nameSize = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8);
i += 2;
System.out.println( "val: " + val + "nameSize: " + nameSize);
String attrName = new String( value, i, nameSize);
System.out.println( "attrName : " + attrName);
PwrtStatus ret = gdh.setObjectInfo( attrName, bvalue);
int sts = ret.getSts();
byte[] msg = new byte[11];
msg[0] = (byte)130;
msg[1] = 9;
msg[2] = SET_OBJECT_INFO_BOOLEAN;
msg[3] = (byte)(id >> 24);
msg[4] = (byte)((id >> 16) & 0xFF);
msg[5] = (byte)((id >> 8) & 0xFF);
msg[6] = (byte)(id & 0xFF);
msg[7] = (byte)(sts >> 24);
msg[8] = (byte)((sts >> 16) & 0xFF);
msg[9] = (byte)((sts >> 8) & 0xFF);
msg[10] = (byte)(sts & 0xFF);
if ( debug)
System.out.println( "Sending: " + msg);
out.write( msg);
out.flush();
}
catch(IOException e) {
System.out.println("SetObjectInfoBoolean: IO exception");
}
break;
case SET_OBJECT_INFO_INT:
try {
int i = 6;
int ivalue = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8) + ((value[i+2] & 0xFF) << 16) + ((value[i+3] & 0xFF) << 24);
i += 4;
int nameSize = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8);
i += 2;
System.out.println( "val: " + ivalue + "nameSize: " + nameSize);
String attrName = new String( value, i, nameSize);
System.out.println( "attrName : " + attrName);
PwrtStatus ret = gdh.setObjectInfo( attrName, ivalue);
int sts = ret.getSts();
byte[] msg = new byte[11];
msg[0] = (byte)130;
msg[1] = 9;
msg[2] = SET_OBJECT_INFO_INT;
msg[3] = (byte)(id >> 24);
msg[4] = (byte)((id >> 16) & 0xFF);
msg[5] = (byte)((id >> 8) & 0xFF);
msg[6] = (byte)(id & 0xFF);
msg[7] = (byte)(sts >> 24);
msg[8] = (byte)((sts >> 16) & 0xFF);
msg[9] = (byte)((sts >> 8) & 0xFF);
msg[10] = (byte)(sts & 0xFF);
if ( debug)
System.out.println( "Sending: " + msg);
out.write( msg);
out.flush();
}
catch(IOException e) {
System.out.println("SefObjectInfoInt: IO exception");
}
break;
case SET_OBJECT_INFO_FLOAT:
try {
int i = 6;
float fvalue = Float.intBitsToFloat(((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8) + ((value[i+2] & 0xFF) << 16) + ((value[i+3] & 0xFF) << 24));
i += 4;
int nameSize = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8);
i += 2;
System.out.println( "val: " + fvalue + " nameSize: " + nameSize);
String attrName = new String( value, i, nameSize);
System.out.println( "attrName : " + attrName);
PwrtStatus ret = gdh.setObjectInfo( attrName, fvalue);
int sts = ret.getSts();
byte[] msg = new byte[11];
msg[0] = (byte)130;
msg[1] = 9;
msg[2] = SET_OBJECT_INFO_FLOAT;
msg[3] = (byte)(id >> 24);
msg[4] = (byte)((id >> 16) & 0xFF);
msg[5] = (byte)((id >> 8) & 0xFF);
msg[6] = (byte)(id & 0xFF);
msg[7] = (byte)(sts >> 24);
msg[8] = (byte)((sts >> 16) & 0xFF);
msg[9] = (byte)((sts >> 8) & 0xFF);
msg[10] = (byte)(sts & 0xFF);
if ( debug)
System.out.println( "Sending: " + msg);
out.write( msg);
out.flush();
}
catch(IOException e) {
System.out.println("SefObjectInfoFloat: IO exception");
}
break;
case SET_OBJECT_INFO_STRING:
try {
int i = 6;
int valSize = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8);
i += 2;
String val = new String( value, i, valSize);
i += valSize;
int nameSize = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8);
i += 2;
System.out.println( "val: " + val + "nameSize: " + nameSize);
String attrName = new String( value, i, nameSize);
System.out.println( "attrName : " + attrName);
PwrtStatus ret = gdh.setObjectInfo( attrName, val);
int sts = ret.getSts();
byte[] msg = new byte[11];
msg[0] = (byte)130;
msg[1] = 9;
msg[2] = SET_OBJECT_INFO_STRING;
msg[3] = (byte)(id >> 24);
msg[4] = (byte)((id >> 16) & 0xFF);
msg[5] = (byte)((id >> 8) & 0xFF);
msg[6] = (byte)(id & 0xFF);
msg[7] = (byte)(sts >> 24);
msg[8] = (byte)((sts >> 16) & 0xFF);
msg[9] = (byte)((sts >> 8) & 0xFF);
msg[10] = (byte)(sts & 0xFF);
if ( debug)
System.out.println( "Sending: " + msg);
out.write( msg);
out.flush();
}
catch(IOException e) {
System.out.println("SefObjectInfoString: IO exception");
}
break;
case TOGGLE_OBJECT_INFO:
try {
int i = 6;
int nameSize = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8);
i += 2;
String attrName = new String( value, i, nameSize);
System.out.println( "attrName : " + attrName);
PwrtStatus ret = gdh.toggleObjectInfo( attrName);
int sts = ret.getSts();
byte[] msg = new byte[11];
msg[0] = (byte)130;
msg[1] = 9;
msg[2] = TOGGLE_OBJECT_INFO;
msg[3] = (byte)(id >> 24);
msg[4] = (byte)((id >> 16) & 0xFF);
msg[5] = (byte)((id >> 8) & 0xFF);
msg[6] = (byte)(id & 0xFF);
msg[7] = (byte)(sts >> 24);
msg[8] = (byte)((sts >> 16) & 0xFF);
msg[9] = (byte)((sts >> 8) & 0xFF);
msg[10] = (byte)(sts & 0xFF);
if ( debug)
System.out.println( "Sending: " + msg);
out.write( msg);
out.flush();
}
catch(IOException e) {
System.out.println("ToggleObjectInfo: IO exception");
}
break;
case REF_OBJECT_INFO:
try {
int i = 6;
int refId = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8) + ((value[i+2] & 0xFF) << 16) + ((value[i+3] & 0xFF) << 24);
i += 4;
int elements = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8) + ((value[i+2] & 0xFF) << 16) + ((value[i+3] & 0xFF) << 24);
i += 4;
int nameSize = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8) + ((value[i+2] & 0xFF) << 16) + ((value[i+3] & 0xFF) << 24);
i += 4;
System.out.println( "nameSize: " + nameSize);
String attrName = new String( value, i, nameSize);
System.out.println( "attrName : " + attrName + " " + threadNumber + " " + refId);
Sub ret = this.refObjectInfo(attrName, threadNumber, refId, elements);
System.out.println( "ret.sts " + ret.getSts() + " sub.subscriptionsIndex " + ret.subscriptionsIndex);
if ( ret.oddSts())
thSub.add(ret);
int sts = ret.getSts();
// if ( debug)
System.out.println( "refObjectInfo: " + id + " refId " + refId + " subidx " + ret.subscriptionsIndex + " " + attrName + " sts: " + ret.getSts() + " type " + ret.typeId);
i += nameSize;
for ( int k = 0; k < thSub.size(); k++) {
if ( thSub.elementAt(k) == null)
continue;
System.out.println( "thSub rcv " + k + " subidx " + ((Sub)thSub.elementAt(k)).subscriptionsIndex + " thSub " + thSub.elementAt(k));
}
sts = 111;
byte[] msg = new byte[11];
msg[0] = (byte)130;
msg[1] = 9;
msg[2] = REF_OBJECT_INFO;
msg[3] = (byte)(id >> 24);
msg[4] = (byte)((id >> 16) & 0xFF);
msg[5] = (byte)((id >> 8) & 0xFF);
msg[6] = (byte)(id & 0xFF);
msg[7] = (byte)(sts >> 24);
msg[8] = (byte)((sts >> 16) & 0xFF);
msg[9] = (byte)((sts >> 8) & 0xFF);
msg[10] = (byte)(sts & 0xFF);
if ( debug)
System.out.println( "Sending: " + msg);
out.write( msg);
out.flush();
}
catch(IOException e) {
System.out.println("RefObjectInfo: IO exception");
}
break;
case UNREF_OBJECT_INFO:
try {
int i = 6;
int subId = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8) + ((value[i+2] & 0xFF) << 16) + ((value[i+3] & 0xFF) << 24);
i += 4;
boolean found = false;
Sub tsub = null;
int idx = 0;
for ( int j = 0; j < thSub.size(); j++) {
tsub = thSub.elementAt(j);
if ( tsub == null)
continue;
if ( subId == tsub.subscriptionsIndex) {
idx = j;
found = true;
break;
}
}
if ( !found)
break;
System.out.println("UnrefObjectInfo: " + subId + " refId: " + tsub.refid.rix);
PwrtStatus rsts = this.unrefObjectInfo( tsub.subId, threadNumber);
thSub.set( idx, null);
int sts = rsts.getSts();
byte[] msg = new byte[11];
msg[0] = (byte)130;
msg[1] = 9;
msg[2] = UNREF_OBJECT_INFO;
msg[3] = (byte)(id >> 24);
msg[4] = (byte)((id >> 16) & 0xFF);
msg[5] = (byte)((id >> 8) & 0xFF);
msg[6] = (byte)(id & 0xFF);
msg[7] = (byte)(sts >> 24);
msg[8] = (byte)((sts >> 16) & 0xFF);
msg[9] = (byte)((sts >> 8) & 0xFF);
msg[10] = (byte)(sts & 0xFF);
if ( debug)
System.out.println( "Sending: " + msg);
out.write( msg);
out.flush();
}
catch(IOException e) {
System.out.println("UnrefObjectInfo: IO exception");
}
break;
case REF_OBJECT_INFO_LIST:
try {
int i = 6;
int subSize = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8) + ((value[i+2] & 0xFF) << 16) + ((value[i+3] & 0xFF) << 24);
i += 4;
for ( int j = 0; j < subSize; j++) {
int refId = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8) + ((value[i+2] & 0xFF) << 16) + ((value[i+3] & 0xFF) << 24);
i += 4;
int elements = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8) + ((value[i+2] & 0xFF) << 16) + ((value[i+3] & 0xFF) << 24);
i += 4;
int nameSize = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8) + ((value[i+2] & 0xFF) << 16) + ((value[i+3] & 0xFF) << 24);
i += 4;
System.out.println( "nameSize: " + nameSize);
String attrName = new String( value, i, nameSize);
System.out.println( "attrName : " + attrName + " " + threadNumber + " " + refId);
Sub ret = this.refObjectInfo(attrName, threadNumber, refId, elements);
System.out.println( "ret.sts " + ret.getSts() + " sub.subscriptionsIndex " + ret.subscriptionsIndex);
thSub.add(ret);
System.out.println( " sub " + ret.subscriptionsIndex + " thSub " + ((Sub)thSub.elementAt(j)).subscriptionsIndex + " sub " + ret + " thSub " + thSub.elementAt(j));
int sts = ret.getSts();
// if ( debug)
System.out.println( "refObjectInfoList: " + id + " refId " + refId + " subidx " + ret.subscriptionsIndex + " " + attrName + " sts: " + ret.getSts() + " type " + ret.typeId);
i += nameSize;
}
for ( int k = 0; k < thSub.size(); k++)
System.out.println( "thSub rcv " + k + " subidx " + ((Sub)thSub.elementAt(k)).subscriptionsIndex + " thSub " + thSub.elementAt(k));
int sts = 111;
byte[] msg = new byte[11];
msg[0] = (byte)130;
msg[1] = 9;
msg[2] = REF_OBJECT_INFO_LIST;
msg[3] = (byte)(id >> 24);
msg[4] = (byte)((id >> 16) & 0xFF);
msg[5] = (byte)((id >> 8) & 0xFF);
msg[6] = (byte)(id & 0xFF);
msg[7] = (byte)(sts >> 24);
msg[8] = (byte)((sts >> 16) & 0xFF);
msg[9] = (byte)((sts >> 8) & 0xFF);
msg[10] = (byte)(sts & 0xFF);
if ( debug)
System.out.println( "Sending: " + msg);
out.write( msg);
out.flush();
}
catch(IOException e) {
System.out.println("RefObjectInfoList: IO exception");
}
break;
case GET_OBJECT_REF_INFO_ALL: {
int sts = 123;
int refsize = 0;
int cnt = 0;
int j;
for ( int i = 0; i < thSub.size(); i++) {
Sub asub = (Sub)thSub.elementAt(i);
if ( asub == null)
continue;
switch( asub.typeId) {
case Pwr.eType_Boolean:
refsize += 8 + 1;
cnt++;
break;
case Pwr.eType_Float32:
if ( asub.elements < 1)
refsize += 8 + 4;
else
refsize += 8 + asub.elements * 4;
cnt++;
break;
case Pwr.eType_Int8:
case Pwr.eType_Int16:
case Pwr.eType_Int32:
case Pwr.eType_UInt8:
case Pwr.eType_UInt16:
case Pwr.eType_UInt32:
case Pwr.eType_Status:
case Pwr.eType_Mask:
case Pwr.eType_Enum:
refsize += 8 + 4;
cnt++;
break;
case Pwr.eType_String:
case Pwr.eType_Time:
case Pwr.eType_DeltaTime:
case Pwr.eType_AttrRef:
case Pwr.eType_Objid:
refsize += 8 + 2;
String svalue = gdh.getObjectRefInfoString(asub.id, asub.typeId);
refsize += svalue.length();
cnt++;
break;
default:
continue;
}
System.out.println("GetAll " + cnt + " " + refsize);
}
//System.out.println("RefObjectListAll send " + (13 + refsize));
byte[] msg;
int jstart;
if ( refsize + 13 < 125) {
jstart = 15;
msg = new byte[15 + refsize];
msg[0] = (byte)130;
msg[1] = (byte)(13 + refsize);
j = 2;
}
else {
jstart = 17;
msg = new byte[17 + refsize];
msg[0] = (byte)130;
msg[1] = (byte)126;
msg[2] = (byte)(((13 + refsize) >> 8) & 0xFF);
msg[3] = (byte)((13 + refsize) & 0xFF);
j = 4;
}
msg[j++] = GET_OBJECT_REF_INFO_ALL;
msg[j++] = (byte)(id >> 24);
msg[j++] = (byte)((id >> 16) & 0xFF);
msg[j++] = (byte)((id >> 8) & 0xFF);
msg[j++] = (byte)(id & 0xFF);
msg[j++] = (byte)(sts >> 24);
msg[j++] = (byte)((sts >> 16) & 0xFF);
msg[j++] = (byte)((sts >> 8) & 0xFF);
msg[j++] = (byte)(sts & 0xFF);
ByteBuffer bb = ByteBuffer.wrap( msg);
for ( int k = 0; k < thSub.size(); k++) {
if ( thSub.elementAt(k) == null)
continue;
// System.out.println( "thSub " + k + " subidx " + ((Sub)thSub.elementAt(k)).subscriptionsIndex);
}
bb.putInt( j, cnt);
j += 4;
for ( int i = 0; i < thSub.size(); i++) {
Sub asub = (Sub)thSub.elementAt(i);
if ( asub == null)
continue;
switch( asub.typeId) {
case Pwr.eType_Boolean:
bb.putInt( j, asub.subscriptionsIndex);
j += 4;
bb.putInt( j, 1);
j += 4;
boolean bvalue = gdh.getObjectRefInfoBoolean(asub.id);
bb.put( j, bvalue ? (byte)1 : (byte)0);
j += 1;
System.out.println( i + " Idx " + asub.subscriptionsIndex + " Value: " + bvalue + " Type " + asub.typeId + " " + (refsize) + " " + (j-jstart));
break;
case Pwr.eType_Float32:
bb.putInt( j, asub.subscriptionsIndex);
j += 4;
if ( asub.elements <= 1) {
bb.putInt( j, 4);
j += 4;
float fvalue = gdh.getObjectRefInfoFloat(asub.id);
bb.putFloat( j, fvalue);
j += 4;
System.out.println( i + " Idx " + asub.subscriptionsIndex + " Value: " + fvalue + " Type " + asub.typeId + " " + (refsize) + " " + (j-jstart));
}
else {
bb.putInt( j, asub.elements * 4);
j += 4;
float[] fvalue = gdh.getObjectRefInfoFloatArray(asub.id, asub.elements);
for ( int k = 0; k < asub.elements; k++) {
if ( k < fvalue.length)
bb.putFloat( j, fvalue[k]);
else
bb.putFloat( j, 0F);
j += 4;
}
System.out.println( i + " Idx " + asub.subscriptionsIndex + " Value: " + fvalue[0] + " Type " + asub.typeId + " " + asub.elements + " " + (refsize) + " " + (j-jstart));
}
break;
case Pwr.eType_Int8:
case Pwr.eType_Int16:
case Pwr.eType_Int32:
case Pwr.eType_UInt8:
case Pwr.eType_UInt16:
case Pwr.eType_UInt32:
case Pwr.eType_Status:
case Pwr.eType_Mask:
case Pwr.eType_Enum:
bb.putInt( j, asub.subscriptionsIndex);
j += 4;
bb.putInt( j, 4);
j += 4;
System.out.println( "getObjectRefInfoInt " + asub.id);
int ivalue = gdh.getObjectRefInfoInt(asub.id);
bb.putInt( j, ivalue);
j += 4;
System.out.println( i + " Idx " + asub.subscriptionsIndex + " Value: " + ivalue + " Type " + asub.typeId + " " + (refsize) + " " + (j-jstart));
break;
case Pwr.eType_String:
case Pwr.eType_Time:
case Pwr.eType_DeltaTime:
case Pwr.eType_AttrRef:
case Pwr.eType_Objid:
bb.putInt( j, asub.subscriptionsIndex);
j += 4;
String svalue = gdh.getObjectRefInfoString(asub.id, asub.typeId);
bb.putInt( j, 2 + svalue.length());
j += 4;
bb.putShort( j, (short)svalue.length());
j += 2;
for ( int k = 0; k < svalue.length(); k++) {
bb.put( j++, (byte)svalue.charAt(k));
}
System.out.println( i + " Idx " + asub.subscriptionsIndex + " Value: " + svalue + " Type " + asub.typeId + " " + (refsize) + " " + (j-jstart));
break;
default:
System.out.println( "***" + i + " Idx " + asub.subscriptionsIndex + " Type " + asub.typeId + " " + (refsize) + " " + (j-jstart));
continue;
}
}
//if ( debug)
// System.out.println( "GetRefObjectInfoAll Sending: " + (refsize+15) + " " + j + " " + msg);
try {
out.write( msg);
out.flush();
}
catch(IOException e) {
System.out.println("GetRefObjectInfoAll failed" + e.toString());
}
break;
}
case GET_ALL_XTT_CHILDREN: {
try {
PwrtObjid objid = new PwrtObjid(0,0);
int i = 6;
objid.vid = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8) + ((value[i+2] & 0xFF) << 16) + ((value[i+3] & 0xFF) << 24);
i += 4;
objid.oix = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8) + ((value[i+2] & 0xFF) << 16) + ((value[i+3] & 0xFF) << 24);
i += 4;
String name = null;
String fullName = null;
String description = " ";
String className = null;
CdhrObjid cdhrObjId;
CdhrClassId cdhrClassId;
boolean hasChildren = false;
int sts = 2;
Vector<GdhrGetXttObj> v = new Vector<GdhrGetXttObj>();
CdhrObjid classObj;
if ( objid.oix == 0)
cdhrObjId = (CdhrObjid)gdh.getRootList();
else
cdhrObjId = (CdhrObjid)gdh.getChild(objid);
while(cdhrObjId.oddSts()) {
cdhrClassId = gdh.getObjectClass(cdhrObjId.objid);
if(cdhrClassId.oddSts()) {
classObj = gdh.classIdToObjid(cdhrClassId.classId);
if (classObj.oddSts()) {
className = gdh.objidToName(classObj.objid, Cdh.mName_object).str;
fullName = gdh.objidToName(cdhrObjId.objid, Cdh.mName_pathStrict).str;
name = gdh.objidToName(cdhrObjId.objid, Cdh.mName_object).str;
CdhrString ret = gdh.getObjectInfoString(fullName + ".Description");
if (ret.oddSts()) {
description = ret.str;
}
else {
description = " ";
}
sts = 1;
if (gdh.getChild(cdhrObjId.objid).oddSts()) {
hasChildren = true;
}
}
}
v.add(new GdhrGetXttObj(name,
fullName,
description,
className,
cdhrObjId,
cdhrClassId,
sts,
hasChildren));
cdhrObjId = gdh.getNextSibling(cdhrObjId.objid);
hasChildren = false;
}
int j;
int refsize = 0;
for ( i = 0; i < v.size(); i++) {
GdhrGetXttObj ve = v.get(i);
refsize += 8; // Objid
refsize += 4; // Cid
refsize += 2; // hasChildren
refsize += 2; // name length
refsize += ve.name.length();
refsize += 2; // description length
refsize += ve.description.length();
refsize += 2; // className length
refsize += ve.className.length();
}
byte[] msg;
if ( refsize + 13 < 125) {
msg = new byte[15 + refsize + 1]; // One extra byte needed for ByteBuffer ??
msg[0] = (byte)130;
msg[1] = (byte)(13 + refsize + 1);
j = 2;
}
else {
msg = new byte[17 + refsize + 1];
msg[0] = (byte)130;
msg[1] = (byte)126;
msg[2] = (byte)(((13 + refsize + 1) >> 8) & 0xFF);
msg[3] = (byte)((13 + refsize + 1) & 0xFF);
j = 4;
}
msg[j++] = GET_ALL_XTT_CHILDREN;
msg[j++] = (byte)(id >> 24);
msg[j++] = (byte)((id >> 16) & 0xFF);
msg[j++] = (byte)((id >> 8) & 0xFF);
msg[j++] = (byte)(id & 0xFF);
msg[j++] = (byte)(sts >> 24);
msg[j++] = (byte)((sts >> 16) & 0xFF);
msg[j++] = (byte)((sts >> 8) & 0xFF);
msg[j++] = (byte)(sts & 0xFF);
ByteBuffer bb = ByteBuffer.wrap( msg);
bb.putInt( j, v.size());
j += 4;
for ( i = 0; i < v.size(); i++) {
GdhrGetXttObj ve = v.get(i);
bb.putInt( j, ve.cdhrObjId.objid.vid);
j += 4;
bb.putInt( j, ve.cdhrObjId.objid.oix);
j += 4;
bb.putInt( j, ve.cdhrClassId.classId);
j += 4;
bb.putShort( j, ve.hasChildren ? (short)1 : (short)0);
j += 2;
bb.putShort( j, (short)ve.name.length());
j += 2;
for ( int k = 0; k < ve.name.length(); k++) {
bb.put( j++, (byte)ve.name.charAt(k));
}
bb.putShort( j, (short)ve.description.length());
j += 2;
for ( int k = 0; k < ve.description.length(); k++)
bb.put( j++, (byte)ve.description.charAt(k));
bb.putShort( j, (short)ve.className.length());
j += 2;
for ( int k = 0; k < ve.className.length(); k++) {
bb.put( j, (byte)ve.className.charAt(k));
j++;
}
}
out.write( msg);
out.flush();
}
catch(IOException e) {
System.out.println("getAllXttChildren: IO exception");
}
break;
}
case GET_ALL_CLASS_ATTRIBUTES: {
try {
int sts = 1;
PwrtObjid objid = new PwrtObjid( 0, 0);
int i = 6;
int classid = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8) + ((value[i+2] & 0xFF) << 16) + ((value[i+3] & 0xFF) << 24);
i += 4;
objid.vid = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8) + ((value[i+2] & 0xFF) << 16) + ((value[i+3] & 0xFF) << 24);
i += 4;
objid.oix = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8) + ((value[i+2] & 0xFF) << 16) + ((value[i+3] & 0xFF) << 24);
i += 4;
System.out.println("GetAllClassAttr " + classid + " " + objid.vid + " " + objid.oix);
Vector<CdhrObjAttr> v = gdh.getAllClassAttributes(classid, objid);
for ( int j = 0; j < v.size(); j++) {
CdhrObjAttr ve = v.get(j);
System.out.println( "Attr: " + ve.name);
}
int j;
int refsize = 0;
for ( i = 0; i < v.size(); i++) {
CdhrObjAttr ve = v.get(i);
refsize += 4; // Type
refsize += 4; // Flags
refsize += 2; // Size
refsize += 2; // Elements
refsize += 2; // name length
refsize += ve.name.length();
refsize += 2; // className length
if ( (ve.flags & Pwr.mAdef_class) != 0)
refsize += ve.className.length();
}
byte[] msg;
if ( refsize + 13 < 125) {
msg = new byte[15 + refsize + 1]; // One extra byte needed for ByteBuffer ??
msg[0] = (byte)130;
msg[1] = (byte)(13 + refsize + 1);
j = 2;
}
else {
msg = new byte[17 + refsize + 1];
msg[0] = (byte)130;
msg[1] = (byte)126;
msg[2] = (byte)(((13 + refsize + 1) >> 8) & 0xFF);
msg[3] = (byte)((13 + refsize + 1) & 0xFF);
j = 4;
}
msg[j++] = GET_ALL_CLASS_ATTRIBUTES;
msg[j++] = (byte)(id >> 24);
msg[j++] = (byte)((id >> 16) & 0xFF);
msg[j++] = (byte)((id >> 8) & 0xFF);
msg[j++] = (byte)(id & 0xFF);
msg[j++] = (byte)(sts >> 24);
msg[j++] = (byte)((sts >> 16) & 0xFF);
msg[j++] = (byte)((sts >> 8) & 0xFF);
msg[j++] = (byte)(sts & 0xFF);
ByteBuffer bb = ByteBuffer.wrap( msg);
bb.putInt( j, v.size());
j += 4;
for ( i = 0; i < v.size(); i++) {
CdhrObjAttr ve = v.get(i);
bb.putInt( j, ve.type);
j += 4;
bb.putInt( j, ve.flags);
j += 4;
bb.putShort( j, (short)ve.size);
j += 2;
bb.putShort( j, (short)ve.elements);
j += 2;
bb.putShort( j, (short)ve.name.length());
j += 2;
for ( int k = 0; k < ve.name.length(); k++)
bb.put( j++, (byte)ve.name.charAt(k));
if ( (ve.flags & Pwr.mAdef_class) != 0) {
bb.putShort( j, (short)ve.className.length());
j += 2;
for ( int k = 0; k < ve.className.length(); k++)
bb.put( j++, (byte)ve.className.charAt(k));
}
else {
bb.putShort( j, (short)0);
j += 2;
}
}
out.write( msg);
out.flush();
}
catch ( IOException e) {
System.out.println("getAllClassAttributes: IO exception");
}
break;
}
case GET_OBJECT:
case GET_OBJECT_FROM_NAME: {
try {
int sts = 1;
PwrtObjid objid = new PwrtObjid( 0, 0);
PwrtObjid retobjid = new PwrtObjid( 0, 0);
int i = 6;
int op = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8);
i += 2;
if ( value[0] == GET_OBJECT) {
objid.vid = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8) + ((value[i+2] & 0xFF) << 16) + ((value[i+3] & 0xFF) << 24);
i += 4;
objid.oix = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8) + ((value[i+2] & 0xFF) << 16) + ((value[i+3] & 0xFF) << 24);
i += 4;
}
else {
int nameSize = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8);
i += 2;
String objName = new String( value, i, nameSize);
i += nameSize;
CdhrObjid oret = gdh.nameToObjid(objName);
if ( oret.evenSts())
sts = oret.getSts();
else {
objid = oret.objid;
}
}
System.out.println( "GET_OBJECT " + op +": " + objid.vid + " " + objid.oix);
if ( (sts & 1) != 0) {
switch ( op) {
case GET_OP_METHOD_PLC: {
CdhrClassId cdhrClassId = gdh.getObjectClass( objid);
if( cdhrClassId.evenSts()) {
sts = cdhrClassId.getSts();
System.out.println("sts1 " + sts);
break;
}
if ( cdhrClassId.classId == Pwrb.cClass_plc) {
CdhrObjid cdhrObjid = (CdhrObjid)gdh.getChild(objid);
if ( cdhrObjid.evenSts()) {
sts = cdhrObjid.getSts();
System.out.println("sts2 " + sts);
break;
}
retobjid = cdhrObjid.objid;
}
else {
retobjid.vid = objid.vid;
retobjid.oix = objid.oix;
}
break;
}
default:
retobjid.vid = objid.vid;
retobjid.oix = objid.oix;
break;
}
}
System.out.println("sts3 " + sts);
String name = null;
String fullName = null;
String description = "";
String className = null;
CdhrObjid cdhrObjId;
int cid = 0;
CdhrClassId cdhrClassId;
boolean hasChildren = false;
String param1 = "";
if ( (sts & 1) != 0) {
cdhrClassId = gdh.getObjectClass(retobjid);
if(cdhrClassId.oddSts()) {
cid = cdhrClassId.classId;
CdhrObjid classObj = gdh.classIdToObjid(cdhrClassId.classId);
if (classObj.oddSts()) {
className = gdh.objidToName( classObj.objid, Cdh.mName_object).str;
fullName = gdh.objidToName( retobjid, Cdh.mName_pathStrict).str;
name = gdh.objidToName( retobjid, Cdh.mName_object).str;
CdhrString ret = gdh.getObjectInfoString(fullName + ".Description");
if (ret.oddSts())
description = ret.str;
else
description = "";
if (gdh.getChild(retobjid).oddSts()) {
hasChildren = true;
}
}
else
sts = classObj.getSts();
}
else
sts = cdhrClassId.getSts();
System.out.println( "sts: " + sts + " name " + fullName + " class " + className + " descr " + description);
if ( op == GET_OP_METHOD_OBJECTGRAPH && (sts & 1) != 0) {
String suffix = "";
cdhrClassId = gdh.getObjectClass( retobjid);
cid = cdhrClassId.classId;
String path = System.getenv("pwrp_web") + "/";
String pwgname;
while ( true) {
CdhrObjid coid = gdh.classIdToObjid( cid);
if ( coid.evenSts()) {
sts = coid.getSts();
break;
}
CdhrString sret = gdh.objidToName( coid.objid, Cdh.mName_object);
if ( sret.evenSts()) {
sts = sret.getSts();
break;
}
// Find any GraphConfiguration suffix
CdhrInt gcret = gdh.getObjectInfoInt( fullName + ".GraphConfiguration");
if ( gcret.oddSts()) {
if ( gcret.value > 0)
suffix = Integer.toString(gcret.value);
}
if ( coid.objid.vid < Cdh.cUserClassVolMin ||
(coid.objid.vid >= Cdh.cManufactClassVolMin &&
coid.objid.vid <= Cdh.cManufactClassVolMax)) {
// Class is a base class, java classname starts with pwr_c_
if (sret.str.startsWith("$"))
pwgname = "pwr_c_" + sret.str.toLowerCase().substring(1) + suffix;
else
pwgname = "pwr_c_" + sret.str.toLowerCase() + suffix;
}
else
pwgname = sret.str.toLowerCase() + suffix;
File file = new File( path + pwgname + ".pwg");
System.out.println("Check file " + path + pwgname + ".pwg");
if ( file.exists()) {
param1 = pwgname;
break;
}
// Check superclass
CdhrClassId rcid = gdh.getSuperClass( cid, null);
if ( rcid.evenSts()) {
sts = rcid.getSts();
break;
}
cid = rcid.classId;
}
}
}
int j;
int refsize = 0;
if ( (sts & 1) != 0) {
refsize += 8; // Objid
refsize += 4; // Cid
refsize += 2; // Has children
refsize += 2; // Name length
refsize += name.length();
refsize += 2; // Fullname length
refsize += fullName.length();
refsize += 2; // Class length
refsize += className.length();
refsize += 2; // Description length
refsize += description.length();
refsize += 2; // Param1 length
refsize += param1.length();
}
byte[] msg;
if ( refsize + 9 < 125) {
msg = new byte[11 + refsize + 1]; // One extra byte needed for ByteBuffer ??
msg[0] = (byte)130;
msg[1] = (byte)(9 + refsize + 1);
j = 2;
}
else {
msg = new byte[13 + refsize + 1];
msg[0] = (byte)130;
msg[1] = (byte)126;
msg[2] = (byte)(((9 + refsize + 1) >> 8) & 0xFF);
msg[3] = (byte)((9 + refsize + 1) & 0xFF);
j = 4;
}
if ( value[0] == GET_OBJECT)
msg[j++] = GET_OBJECT;
else
msg[j++] = GET_OBJECT_FROM_NAME;
msg[j++] = (byte)(id >> 24);
msg[j++] = (byte)((id >> 16) & 0xFF);
msg[j++] = (byte)((id >> 8) & 0xFF);
msg[j++] = (byte)(id & 0xFF);
msg[j++] = (byte)(sts >> 24);
msg[j++] = (byte)((sts >> 16) & 0xFF);
msg[j++] = (byte)((sts >> 8) & 0xFF);
msg[j++] = (byte)(sts & 0xFF);
if ( (sts & 1) != 0) {
ByteBuffer bb = ByteBuffer.wrap( msg);
bb.putInt( j, retobjid.vid);
j += 4;
bb.putInt( j, retobjid.oix);
j += 4;
bb.putInt( j, cid);
j += 4;
bb.putShort( j, hasChildren ? (short)1 : (short)0);
j += 2;
bb.putShort( j, (short)name.length());
j += 2;
for ( int k = 0; k < name.length(); k++)
bb.put( j++, (byte)name.charAt(k));
bb.putShort( j, (short)fullName.length());
j += 2;
for ( int k = 0; k < fullName.length(); k++)
bb.put( j++, (byte)fullName.charAt(k));
bb.putShort( j, (short)className.length());
j += 2;
for ( int k = 0; k < className.length(); k++)
bb.put( j++, (byte)className.charAt(k));
bb.putShort( j, (short)description.length());
j += 2;
for ( int k = 0; k < description.length(); k++)
bb.put( j++, (byte)description.charAt(k));
bb.putShort( j, (short)param1.length());
j += 2;
for ( int k = 0; k < param1.length(); k++)
bb.put( j++, (byte)param1.charAt(k));
}
out.write( msg);
out.flush();
}
catch ( IOException e) {
System.out.println("getAllClassAttributes: IO exception");
}
break;
}
case CRR_SIGNAL:
try {
int sts = 1;
PwrtObjid objid = new PwrtObjid(0,0);
int i = 6;
objid.vid = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8) + ((value[i+2] & 0xFF) << 16) + ((value[i+3] & 0xFF) << 24);
i += 4;
objid.oix = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8) + ((value[i+2] & 0xFF) << 16) + ((value[i+3] & 0xFF) << 24);
i += 4;
int refsize;
int crrlen = 0;
CdhrString ret = null;
String[] name = null;
String[] className = null;
PwrtObjid[] oid = null;
int[] ctype = null;
int cid = 0;
CdhrString cdhrString = gdh.objidToName( objid, Cdh.mName_pathStrict);
sts = cdhrString.getSts();
if ( cdhrString.oddSts()) {
CdhrClassId cdhrClassId = gdh.getObjectClass( objid);
sts = cdhrClassId.getSts();
cid = cdhrClassId.getClassId();
}
if ( (sts & 1) != 1) {
sts = cdhrString.getSts();
refsize = 0;
}
else {
System.out.println( "crr " + cdhrString.str);
switch ( cid) {
case Pwrb.cClass_Di:
case Pwrb.cClass_Dv:
case Pwrb.cClass_Do:
case Pwrb.cClass_Ai:
case Pwrb.cClass_Av:
case Pwrb.cClass_Ao:
case Pwrb.cClass_Ii:
case Pwrb.cClass_Iv:
case Pwrb.cClass_Io:
ret = gdh.crrSignal(cdhrString.str);
break;
default:
ret = gdh.crrObject(cdhrString.str);
}
if ( ret.evenSts()) {
System.out.println( "Crossref error: " + ret.getSts());
sts = ret.getSts();
refsize = 0;
}
else {
String delim = new String( new char[] { '\n'});
String[] tokens = ret.str.split( delim);
crrlen = tokens.length;
name = new String[crrlen];
className = new String[crrlen];
oid = new PwrtObjid[crrlen];
ctype = new int[crrlen];
for ( i = 0; i < crrlen; i++) {
System.out.println("Token : " + tokens[i]);
String[] subtokens = tokens[i].substring(1).split("\\s+");
name[i] = subtokens[0];
className[i] = subtokens[1];
if ( tokens[i].startsWith("0"))
ctype[i] = 0;
else if ( tokens[i].startsWith("1"))
ctype[i] = 1;
else
ctype[i] = 2;
CdhrObjid oret = null;
if ( className[i].equals( "XttGraph"))
oret = gdh.nameToObjid(name[i]);
else {
System.out.println("Cossref : " + name[i]);
int idx = name[i].lastIndexOf('-');
if ( idx != -1) {
oret = gdh.nameToObjid(name[i].substring(0,idx));
System.out.println("pwrent " + name[i].substring(0,idx) + " " + oret.objid.vid + " " + oret.objid.oix);
}
else
oret = gdh.nameToObjid(name[i]);
}
if ( oret.oddSts())
oid[i] = oret.objid;
else {
oid[i] = new PwrtObjid(0,0);
}
System.out.println("oid " + oid[i].vid + " " + oid[i].oix);
}
refsize = 2; // Number of elements
for ( i = 0; i < crrlen; i++) {
refsize += 2; // Type
refsize += 8; // Objid
refsize += 2; // Name size
refsize += name[i].length(); // Name
refsize += 2; // Classname size
refsize += className[i].length(); // Classname
}
}
}
byte[] msg;
int j;
if ( refsize + 9 < 125) {
msg = new byte[11 + refsize + 1]; // One extra byte needed for ByteBuffer ??
msg[0] = (byte)130;
msg[1] = (byte)(9 + refsize + 1);
j = 2;
}
else {
msg = new byte[13 + refsize + 1];
msg[0] = (byte)130;
msg[1] = (byte)126;
msg[2] = (byte)(((9 + refsize + 1) >> 8) & 0xFF);
msg[3] = (byte)((9 + refsize + 1) & 0xFF);
j = 4;
}
msg[j++] = CRR_SIGNAL;
msg[j++] = (byte)(id >> 24);
msg[j++] = (byte)((id >> 16) & 0xFF);
msg[j++] = (byte)((id >> 8) & 0xFF);
msg[j++] = (byte)(id & 0xFF);
msg[j++] = (byte)(sts >> 24);
msg[j++] = (byte)((sts >> 16) & 0xFF);
msg[j++] = (byte)((sts >> 8) & 0xFF);
msg[j++] = (byte)(sts & 0xFF);
if ( (sts & 1) != 0) {
ByteBuffer bb = ByteBuffer.wrap( msg);
bb.putShort( j, (short)crrlen);
j += 2;
for ( i = 0; i < crrlen; i++) {
bb.putShort( j, (short)ctype[i]);
j += 2;
bb.putInt( j, oid[i].vid);
j += 4;
bb.putInt( j, oid[i].oix);
j += 4;
bb.putShort( j, (short)name[i].length());
j += 2;
for ( int k = 0; k < name[i].length(); k++)
bb.put( j++, (byte)name[i].charAt(k));
bb.putShort( j, (short)className[i].length());
j += 2;
for ( int k = 0; k < className[i].length(); k++)
bb.put( j++, (byte)className[i].charAt(k));
}
}
out.write( msg);
out.flush();
}
catch(IOException e) {
System.out.println("crrSignal: IO exception");
}
break;
case GET_OPWIND_MENU: {
try {
int sts = 1;
PwrtObjid objid = new PwrtObjid(0,0);
int i = 6;
int len = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8);
i += 2;
String opPlace = new String( value, i, len);
CdhrObjid classObj;
CdhrString ret;
CdhrInt iret;
WebButton button;
String oppTitle = "";
String oppText = "";
int oppEnableLanguage = 0;
int oppEnableLogin = 0;
int oppEnableAlarmList = 0;
int oppEnableEventLog = 0;
int oppEnableNavigator = 0;
int oppDisableHelp = 0;
int oppDisableProview = 0;
int oppLanguage = 0;
CdhrObjid oret;
Vector<WebButton> v = new Vector<WebButton>();
System.out.println("OpPlace \"" + opPlace + "\"");
if ( opPlace.isEmpty()) {
// Get first
oret = gdh.getClassList( Pwrb.cClass_OpPlaceWeb);
if ( oret.evenSts())
sts = oret.getSts();
else {
objid = oret.objid;
opPlace = gdh.objidToName(objid, Cdh.mName_pathStrict).str;
}
}
else {
oret = gdh.nameToObjid(opPlace);
if ( oret.evenSts())
sts = oret.getSts();
else {
objid = oret.objid;
}
}
if ( (sts & 1) != 0) {
ret = gdh.getObjectInfoString(opPlace + ".Title");
if (ret.oddSts())
oppTitle = ret.str;
ret = gdh.getObjectInfoString(opPlace + ".Text");
if (ret.oddSts())
oppText = ret.str;
iret = gdh.getObjectInfoInt(opPlace + ".EnableLanguage");
if (iret.oddSts())
oppEnableLanguage = iret.value;
iret = gdh.getObjectInfoInt(opPlace + ".EnableLogin");
if (iret.oddSts())
oppEnableLogin = iret.value;
iret = gdh.getObjectInfoInt(opPlace + ".EnableAlarmList");
if (iret.oddSts())
oppEnableAlarmList = iret.value;
iret = gdh.getObjectInfoInt(opPlace + ".EnableEventLog");
if (iret.oddSts())
oppEnableEventLog = iret.value;
iret = gdh.getObjectInfoInt(opPlace + ".EnableNavigator");
if (iret.oddSts())
oppEnableNavigator = iret.value;
iret = gdh.getObjectInfoInt(opPlace + ".DisableHelp");
if (iret.oddSts())
oppDisableHelp = iret.value;
iret = gdh.getObjectInfoInt(opPlace + ".DisableProview");
if (iret.oddSts())
oppDisableProview = iret.value;
CdhrObjid cdhrObjId = (CdhrObjid)gdh.getChild(objid);
while(cdhrObjId.oddSts()) {
String childName = gdh.objidToName(cdhrObjId.objid, Cdh.mName_pathStrict).str;
CdhrClassId cdhrClassId = gdh.getObjectClass(cdhrObjId.objid);
if(cdhrClassId.oddSts()) {
button = new WebButton();
switch ( cdhrClassId.classId) {
case Pwrb.cClass_WebGraph:
button.type = WebButton.GRAPH;
ret = gdh.getObjectInfoString(childName + ".Text");
if (ret.oddSts())
button.text = ret.str;
else
button.text = "";
ret = gdh.getObjectInfoString(childName + ".Name");
if (ret.oddSts())
button.name = ret.str;
else
button.name = "";
button.url = "";
v.add( button);
break;
case Pwrb.cClass_WebLink:
button.type = WebButton.LINK;
ret = gdh.getObjectInfoString(childName + ".Text");
if (ret.oddSts())
button.text = ret.str;
else
button.text = "";
ret = gdh.getObjectInfoString(childName + ".URL");
if (ret.oddSts())
button.url = ret.str;
else
button.url = "";
button.name = "";
v.add( button);
break;
}
System.out.println("Child " + childName + " " + button.text + " " + button.name + " " + button.url);
}
cdhrObjId = gdh.getNextSibling(cdhrObjId.objid);
}
}
System.out.println( "GetOpwindMenu " + v.size());
int j;
int refsize = 0;
refsize += 2; // opplace title length
refsize += oppTitle.length();
refsize += 2; // opplace text length
refsize += oppText.length();
refsize += 4; // enable language
refsize += 4; // enable login
refsize += 4; // enable alarmlist
refsize += 4; // enable eventlog
refsize += 4; // enable navigator
refsize += 4; // disable help
refsize += 4; // disable proview
refsize += 4; // language
refsize += 2; // button vector length
if ( (sts & 1) != 0) {
for ( i = 0; i < v.size(); i++) {
WebButton ve = v.get(i);
refsize += 4; // Type
refsize += 2; // text length
refsize += ve.text.length();
refsize += 2; // name length
refsize += ve.name.length();
refsize += 2; // url length
refsize += ve.url.length();
}
}
System.out.println("OpwinMenu refsize " + refsize);
byte[] msg;
if ( refsize + 11 < 125) {
msg = new byte[13 + refsize + 1]; // One extra byte needed for ByteBuffer ??
msg[0] = (byte)130;
msg[1] = (byte)(11 + refsize + 1);
j = 2;
}
else {
msg = new byte[15 + refsize + 1];
msg[0] = (byte)130;
msg[1] = (byte)126;
msg[2] = (byte)(((11 + refsize + 1) >> 8) & 0xFF);
msg[3] = (byte)((11 + refsize + 1) & 0xFF);
j = 4;
}
msg[j++] = GET_OPWIND_MENU;
msg[j++] = (byte)(id >> 24);
msg[j++] = (byte)((id >> 16) & 0xFF);
msg[j++] = (byte)((id >> 8) & 0xFF);
msg[j++] = (byte)(id & 0xFF);
msg[j++] = (byte)(sts >> 24);
msg[j++] = (byte)((sts >> 16) & 0xFF);
msg[j++] = (byte)((sts >> 8) & 0xFF);
msg[j++] = (byte)(sts & 0xFF);
if ( (sts & 1) != 0) {
ByteBuffer bb = ByteBuffer.wrap( msg);
bb.putShort( j, (short)oppTitle.length());
j += 2;
for ( int k = 0; k < oppTitle.length(); k++) {
bb.put( j++, (byte)oppTitle.charAt(k));
}
bb.putShort( j, (short)oppText.length());
j += 2;
for ( int k = 0; k < oppText.length(); k++) {
bb.put( j++, (byte)oppText.charAt(k));
}
bb.putInt( j, oppEnableLanguage);
j += 4;
bb.putInt( j, oppEnableLogin);
j += 4;
bb.putInt( j, oppEnableAlarmList);
j += 4;
bb.putInt( j, oppEnableEventLog);
j += 4;
bb.putInt( j, oppEnableNavigator);
j += 4;
bb.putInt( j, oppDisableHelp);
j += 4;
bb.putInt( j, oppDisableProview);
j += 4;
bb.putInt( j, oppLanguage);
j += 4;
bb.putShort( j, (short)v.size());
j += 2;
for ( i = 0; i < v.size(); i++) {
WebButton ve = v.get(i);
bb.putInt( j, ve.type);
j += 4;
bb.putShort( j, (short)ve.text.length());
j += 2;
for ( int k = 0; k < ve.text.length(); k++) {
bb.put( j++, (byte)ve.text.charAt(k));
}
bb.putShort( j, (short)ve.name.length());
j += 2;
for ( int k = 0; k < ve.name.length(); k++)
bb.put( j++, (byte)ve.name.charAt(k));
bb.putShort( j, (short)ve.url.length());
j += 2;
for ( int k = 0; k < ve.url.length(); k++) {
bb.put( j, (byte)ve.url.charAt(k));
j++;
}
System.out.println("Button " + ve.type + " " + ve.text.length() + " " + ve.name.length() + " " + ve.url.length() );
}
}
out.write( msg);
out.flush();
}
catch(IOException e) {
System.out.println("getOpWindMenu: IO exception");
}
break;
}
case CHECK_USER:
try {
int i = 6;
int len = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8);
i += 2;
String user = new String( value, i, len);
i += len;
len = ((value[i] & 0xFF) << 0) + ((value[i+1] & 0xFF) << 8);
i += 2;
String passwd = new String( value, i, len);
i += len;
int sts = 1;
int priv = 0;
CdhrString retstr =
gdh.getObjectInfoString("pwrNode-System.SystemGroup");
if ( retstr.evenSts())
sts = retstr.getSts();
else {
String systemGroup = retstr.str;
CdhrInt ret = RtSecurity.checkUser( "", user, passwd);
if( ret.evenSts())
sts = ret.getSts();
else
priv = ret.value;
}
byte[] msg = new byte[15];
msg[0] = (byte)130;
msg[1] = 13;
msg[2] = CHECK_USER;
msg[3] = (byte)(id >> 24);
msg[4] = (byte)((id >> 16) & 0xFF);
msg[5] = (byte)((id >> 8) & 0xFF);
msg[6] = (byte)(id & 0xFF);
msg[7] = (byte)(sts >> 24);
msg[8] = (byte)((sts >> 16) & 0xFF);
msg[9] = (byte)((sts >> 8) & 0xFF);
msg[10] = (byte)(sts & 0xFF);
if ( (sts & 1) != 0) {
msg[11] = (byte)(priv >> 24);
msg[12] = (byte)((priv >> 16) & 0xFF);
msg[13] = (byte)((priv >> 8) & 0xFF);
msg[14] = (byte)(priv & 0xFF);
}
if ( debug)
System.out.println( "Sending: " + msg);
out.write( msg);
out.flush();
}
catch(IOException e) {
System.out.println("checkUser: IO exception");
}
break;
default:
System.out.println("Unknown function code received: " + value[0]);
}
}
}
catch ( java.io.IOException e) {
System.out.println("ServerSocket IOException " + e.toString());
}
}
public synchronized Sub refObjectInfo(String attrName, int threadNumber, int refId, int elements)
{
SubElement sub;
int firstUnreffedIndex = subscriptionCount;
boolean notFoundUnreffed = true;
//loopa igenom och titta om vi redan har refererat objektet
/** TODO subscriptionIndex will be wrong
int index = subscriptions.indexOf(new SubElement(attrName));
if(index >= 0)
{
sub = (SubElement)subscriptions.get(index);
sub.reffedByThreadBitSet.set(threadNumber);
sub.reffedByThread[threadNumber]++;
sub.sub.subscriptionsIndex = refId;
return sub.sub;
}
**/
ListIterator iter = subscriptions.listIterator();
while(iter.hasNext())
{
sub = (SubElement)iter.next();
//spara undan eventuellt avreffererat elements index
if(notFoundUnreffed && sub.sub.sts == __UNREFED)
{
firstUnreffedIndex = iter.previousIndex();
notFoundUnreffed = false;
break;
}
}
GdhrRefObjectInfo ret = gdh.refObjectInfo(attrName);
System.out.println("gdh.refObjectInfo " + attrName + " type " + ret.typeId);
if(ret.oddSts())
{
sub = new SubElement(maxConnections, threadNumber);
if(notFoundUnreffed)
{
//System.out.println("this.refObjectInfo ej reffad ej lucka i subsc.. " + attrName + " " + subscriptionCount);
sub.setSub(ret, subscriptionCount, attrName);
sub.sub.subId = subscriptionCount;
subscriptions.add(sub);
subscriptionCount++;
sub.reffedByThreadBitSet.set(threadNumber);
sub.reffedByThread[threadNumber]++;
sub.sub.subscriptionsIndex = refId;
sub.sub.typeId = ret.typeId;
sub.sub.elements = elements;
//lastIndexReffed = subscriptions.size();
}
else
{
//System.out.println("this.refObjectInfo ej reffad " + attrName + " " + firstUnreffedIndex);
sub.setSub(ret, firstUnreffedIndex, attrName);
subscriptions.remove(firstUnreffedIndex);
sub.sub.subId = firstUnreffedIndex;
subscriptions.add(firstUnreffedIndex, sub);
sub.reffedByThreadBitSet.set(threadNumber);
sub.reffedByThread[threadNumber]++;
sub.sub.subscriptionsIndex = refId;
sub.sub.typeId = ret.typeId;
sub.sub.elements = elements;
}
}
else
{
sub = new SubElement(maxConnections, threadNumber);
sub.setSub(ret, -1, " ");
}
return sub.getSub();
}
public synchronized PwrtStatus unrefObjectInfo( int subid, int threadNumber)
{
//System.out.println("unrefObjectInfo");
SubElement sub;
boolean doNotUnrefObject = false;
try
{
//System.out.println("unrefObjectInfo: " + subid);
sub = (SubElement)subscriptions.get(subid);
if(sub.reffedByThread[threadNumber] > 0)
{
sub.reffedByThread[threadNumber]--;
if(sub.reffedByThread[threadNumber] <= 0)
{
sub.reffedByThreadBitSet.clear(threadNumber);
}
}
for(int i = 0; i < sub.reffedByThread.length; i++)
{
if(sub.reffedByThread[i] > 0)
{
doNotUnrefObject = true;
break;
}
}
}
catch(IndexOutOfBoundsException e)
{
System.out.println("unrefObjectInfo : indexoutofbounds");
return new PwrtStatus(2);
}
PwrtStatus ret = new PwrtStatus(1);
if(!doNotUnrefObject)
{
/*
if(refid.rix < lastIndexReffed)
{
lastIndexReffed = refid.rix;
}
*/
ret = gdh.unrefObjectInfo(sub.sub.refid);
sub.sub.sts = __UNREFED;
sub.sub.attrName = " ";
}
//System.out.println("unrefObjectInfo: ret.sts " + ret.getSts());
return ret;
}
public synchronized void trimRefObjectList()
{
SubElement sub;
int i = subscriptions.size();
int oldi = i;
while(i > 0)
{
i--;
sub = (SubElement)subscriptions.get(i);
if(sub.sub.sts == __UNREFED)
{
subscriptions.remove(i);
subscriptionCount--;
}
else
{
break;
}
}
//System.out.println("Minskar subscriptions-listan med " + oldi + " - " + (i + 1));
subscriptions.trimToSize();
System.gc();
System.runFinalization();
//System.out.println("subscriptionsstorlek " + subscriptions.size());
}
/**
Gets the subscriptions attribute of the GdhThread object
@return The subscriptions value
*/
public synchronized ArrayList getSubscriptions()
{
return (ArrayList)subscriptions.clone();
}
}
}
......@@ -336,6 +336,7 @@ public class Pwrb {
public static final int cClass_waith = 133072;
public static final int cClass_WebBrowserConfig = 133488;
public static final int cClass_WebHandler = 133440;
public static final int cClass_WebSocketServer = 136704;
public static final int cClass_OpPlaceWeb = 136528;
public static final int cClass_OpPlaceApp = 136536;
public static final int cClass_WebGraph = 133472;
......
......@@ -42,6 +42,7 @@ local_java_sources = \
SubElement.java \
GdhServer.java \
GdhServerMonitor.java \
GdhWebSocketServer.java \
HistQuery.java \
MhrsEventId.java \
MhrEvent.java \
......
......@@ -36,6 +36,7 @@
#include <ctype.h>
#include "pwr_baseclasses.h"
#include "pwr_remoteclasses.h"
#include "pwr_nmpsclasses.h"
#include "pwr_basecomponentclasses.h"
......@@ -68,6 +69,7 @@
#define cPrio_webmon (cPrio_base + 15)
#define cPrio_webmonmh (cPrio_base + 15)
#define cPrio_webmonelog (cPrio_base + 15)
#define cPrio_websocketserver (cPrio_base + 15)
#define cPrio_elog (cPrio_base + 15)
#define cPrio_sysmon (cPrio_base + 16)
#define cPrio_opc_server (cPrio_base + 15)
......@@ -172,6 +174,10 @@ void ini_ProcTable(pwr_tStatus* status, ini_sContext* cp)
"rt_webmonelog.sh", cPrio_webmonelog, 0, pwr_cClass_WebHandler, "", 0);
pp->proc.flags.b.system = 1;
pp = ini_ProcInsert(sts, cp, "pwr_websocketserver", "pwr_websocketserver_%d", 0, 1,
"rt_websocketserver.sh", cPrio_websocketserver, 0, pwr_cClass_WebSocketServer, "", 0);
pp->proc.flags.b.system = 1;
pp = ini_ProcInsert(sts, cp, "pwr_opc_server", "pwr_opc_server_%d", 0, 1,
"opc_server", cPrio_opc_server, 0, pwr_cClass_Opc_ServerConfig, "", 0);
pp->proc.flags.b.system = 1;
......
#!/bin/bash
#
# ProviewR Open Source Process Control.
# Copyright (C) 2005-2018 SSAB EMEA AB.
#
# This file is part of ProviewR.
#
# 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 2 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 ProviewR. If not, see <http://www.gnu.org/licenses/>
#
# Linking ProviewR statically or dynamically with other modules is
# making a combined work based on ProviewR. Thus, the terms and
# conditions of the GNU General Public License cover the whole
# combination.
#
# In addition, as a special exception, the copyright holders of
# ProviewR give you permission to, from the build function in the
# ProviewR Configurator, combine ProviewR with modules generated by the
# ProviewR PLC Editor to a PLC program, regardless of the license
# terms of these modules. You may copy and distribute the resulting
# combined work under the terms of your choice, provided that every
# copy of the combined work is accompanied by a complete copy of
# the source code of ProviewR (the version used to produce the
# combined work), being distributed under the terms of the GNU
# General Public License plus this exception.
#
#
export LD_LIBRARY_PATH=$pwr_exe
export CLASSPATH=$pwr_lib/pwr_rt.jar:$pwr_lib/pwr_jop.jar
$jdk_home/java -Djava.library.path=$jdk/lib/i386/client:$jdk/lib/i386:$jdk/../lib/i386:$pwr_exe jpwr.rt.GdhWebSocketServer
......@@ -120,6 +120,7 @@ typedef enum {
errh_eAnix_powerlink = 25,
errh_eAnix_videomgm = 26,
errh_eAnix_redcom = 27,
errh_eAnix_websocketserver = 28,
errh_eAnix_plc1 = 41,
errh_eAnix_plc2 = 42,
errh_eAnix_plc3 = 43,
......
0! DefaultWidth 990
0! DefaultHeight 515
0! DefaultHeight 535
199
!/**
! TempSwitch
......@@ -29,22 +29,22 @@
100 20
135 20
101 20
102 -204
103 72
104 3.09562
136 3.09562
102 -38
103 -2
104 3.57009
136 3.57009
105 100
106 -31
106 -7
107 0
108 51.5
109 -2
110 26.0048
110 26.4272
111 0.01322
116 0
117 11
118 117
119 105
120 0
117 0
118 68
119 108
120 1
121 Claes context
122 0
126 0.5
......@@ -63,7 +63,7 @@
134
22
2200 0
2201 548
2201 558
2202 pwr_c_node_servers
2203 310
2205 0
......@@ -74,7 +74,7 @@
2209 0
2210 0
2211 49.5
2212 25.75
2212 26.75
2213 4
2214
pwrp_pop:
......@@ -17479,13 +17479,13 @@ pwr_exe:
0
0
1006 7.25453
1007 1.0158
1008 14.641
1009 13.7277
1007 1.01579
1008 14.6409
1009 13.7276
1013 7.25453
1014 1.0158
1015 14.641
1016 13.7277
1014 1.01579
1015 14.6409
1016 13.7276
1003
0
0
......@@ -21518,5 +21518,854 @@ pwr_exe:
99
99
99
27
2703 370
2704 410
2731 10000
2722 10000
2705 410
2723 10000
2706 370
2732 10000
2708 0
2709 0
2710 0
2711 0
2712 0
2713 0
2714 0
2715 0
2720 0
2725 0
2726 0
2702 0
2701
2700
10
1000 pwr_indsquare
1002 O552
1005
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1006 8.32213
1007 7.5915
1008 26.3477
1009 25.5562
1013 8.32213
1014 7.5915
1015 26.3477
1016 25.5562
1003
0
0
0
0
0
0
0
0
0
0
1004
1001
7
700 5.95
701 8.95
99
1010
1011
1018
1019
1020
1021
1022
1023
1024
1025
1012 0
1017 9999
1027 9999
1026 65532
1028 0
1029
99
2707
28
2800 1.21772
2801 0
2802 7.40884
2803 0
2804 1.21772
2805 25.4344
2806 0
99
2716 0
2718
2717
2719 0
2724 0
2727 0
2728 303
2729 4
2730 0
2721
1
100 33554432
105 0
101 0
106 0
102 65532
103 0
31
3100 $object.ProcStatus[27]##status
3101 374
3102 1
99
99
99
27
2703 310
2704 310
2731 10000
2722 326
2705 310
2723 326
2706 310
2732 10000
2708 0
2709 0
2710 0
2711 0
2712 0
2713 0
2714 0
2715 0
2720 0
2725 0
2726 0
2702 0
2701
2700
10
1000 pwr_valuelong
1002 O553
1005
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1006 25.8189
1007 8.56567
1008 26.3477
1009 25.4953
1013 25.8189
1014 8.56567
1015 26.3477
1016 25.4953
1003
0
0
0
0
0
0
0
0
0
0
1004
1001
7
700 6.75
701 5.6
99
1010
1011
1018
1019
1020
1021
1022
1023
1024
1025
1012 0
1017 9999
1027 9999
1026 65532
1028 0
1029
99
2707
28
2800 0.648618
2801 0
2802 8.56567
2803 0
2804 1.21772
2805 25.4953
2806 0
99
2716 0
2718
2717
2719 0
2724 0
2727 0
2728 303
2729 4
2730 0
2721
1
100 1
105 0
101 1
106 0
102 65532
103 0
12
1200 $object.ProcStatus[27]##status
1201 %1m
1202 1
1203 1
1204 0
1205
1206 0
99
99
99
27
2703 370
2704 410
2731 10000
2722 10000
2705 410
2723 10000
2706 370
2732 10000
2708 0
2709 0
2710 0
2711 0
2712 0
2713 0
2714 0
2715 0
2720 0
2725 0
2726 0
2702 0
2701
2700
10
1000 pwr_indsquare
1002 O554
1005
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1006 27.4404
1007 26.7098
1008 26.3477
1009 25.5562
1013 27.4404
1014 26.7098
1015 26.3477
1016 25.5562
1003
0
0
0
0
0
0
0
0
0
0
1004
1001
7
700 5.95
701 8.95
99
1010
1011
1018
1019
1020
1021
1022
1023
1024
1025
1012 0
1017 9999
1027 9999
1026 65532
1028 0
1029
99
2707
28
2800 1.21772
2801 0
2802 26.5271
2803 0
2804 1.21772
2805 25.4344
2806 0
99
2716 0
2718
2717
2719 0
2724 0
2727 0
2728 303
2729 4
2730 0
2721
1
100 33554432
105 0
101 0
106 0
102 65532
103 0
31
3100 $object.ProcMsgSeverity[27]##status
3101 374
3102 1
99
99
99
27
2703 310
2704 310
2731 10000
2722 326
2705 310
2723 326
2706 310
2732 10000
2708 0
2709 0
2710 0
2711 0
2712 0
2713 0
2714 0
2715 0
2720 0
2725 0
2726 0
2702 0
2701
2700
10
1000 pwr_valuelong
1002 O555
1005
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1006 48.6406
1007 27.623
1008 26.3477
1009 25.4953
1013 48.6406
1014 27.623
1015 26.3477
1016 25.4953
1003
0
0
0
0
0
0
0
0
0
0
1004
1001
7
700 6.75
701 5.6
99
1010
1011
1018
1019
1020
1021
1022
1023
1024
1025
1012 0
1017 9999
1027 9999
1026 65532
1028 0
1029
99
2707
28
2800 0.790134
2801 0
2802 27.623
2803 0
2804 1.21772
2805 25.4953
2806 0
99
2716 0
2718
2717
2719 0
2724 0
2727 0
2728 303
2729 4
2730 0
2721
1
100 1
105 0
101 1
106 0
102 65532
103 0
12
1200 $object.ProcMessage[27]##string80
1201 %s
1202 1
1203 1
1204 0
1205
1206 0
99
99
99
20
2004 O556
2000 49.5
2001 0
2002 26.4272
2003 26.4272
2009 322
2010 0
2005
6
600 322
601 1
602
7
700 49.5
701 13
99
603
7
700 0
701 13
99
99
2008
28
2800 1
2801 0
2802 0
2803 0
2804 1
2805 13.4272
2806 0
99
99
35
3500
27
2703 454
2704 450
2731 10000
2722 458
2705 450
2723 458
2706 454
2732 10000
2708 0
2709 0
2710 0
2711 0
2712 0
2713 0
2714 0
2715 0
2720 0
2725 0
2726 0
2702 0
2701
2700
10
1000 Grp557_
1002 Grp557_
1005
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1006 7.25453
1007 1.01579
1008 26.4085
1009 25.4952
1013 7.25453
1014 1.01579
1015 26.4085
1016 25.4952
1003
0
0
0
0
0
0
0
0
0
0
1004
1001
7
700 0
701 0
99
1010
1011
1018
1019
1020
1021
1022
1023
1024
1025
1012 0
1017 9999
1027 9999
1026 35454972
1028 0
1029
99
2707
28
2800 1
2801 0
2802 0
2803 0
2804 1
2805 1
2806 0
99
2716 0
2718
2717
2719 0
2724 0
2727 0
2728 303
2729 9999
2730 0
2721
1
100 0
105 0
101 66
106 0
102 65535
103 0
50
5000 &$object.ProcObject[27]
99
55
5500 open graph/classgraph/instance=&$object.ProcObject[27]
99
99
99
3501
36
3600
3
300 Grp557_
301
2
19
1904 O387
1900 7.25453
1901 1.01579
1902 25.4085
1903 24.4952
1908 0
1909 30
1910 30
1911 1
1915 1
1913 16
1916 2
1914 0
1918 0
1919 0
1920 0
1917 0
1921 0
1922 4
1923 0
1924 0
1925 10000
1926 0
1907 0
1906
1905
5
500 0
501 1
504 1
505 1
502
7
700 0.95
701 10.6
99
503
7
700 4.5
701 11.35
99
99
1912
28
2800 1.75739
2801 0
2802 -0.653727
2803 0
2804 1.21772
2805 11.5874
2806 0
99
99
30
3004 O388
3000 6.68088
3001 1.63088
3002 25.3887
3003 24.5887
3008 103
3010 4
3011 2
3007 0
3006
3005
9
900 2
901 303
904 0
902 rt_websockets
903
7
700 1.1
701 2.5
99
99
3009
28
2800 1.75739
2801 0
2802 -0.302248
2803 0
2804 1.21772
2805 22.1944
2806 0
99
99
99
302 0
304 0
303
305 0
306
307
308 0
330 0
321 0
331 0
309 0
313 0
322 0
323 0
324 0
325 0
326 0
327 0
310 0
311 0
312
314
315 1
316 1
317 0
318 0
319 0
320 0
328 0
332 0
99
99
99
99
99
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment