Update - You can find a sample project to recreate the issue here: https://github.com/benf1977/j2objc-serialization-example/releases/tag/1.0
I'm trying to serialize an object in Java and pass the bytes over to my Objective-C layer to write to the filesystem. My relevant Java code is this:
/**
* Created by benjamin.flynn on 10/7/15.
*/
public class TestData implements Serializable {
private String mName;
private int mAge;
public TestData(String pName, int pAge) {
mName = pName;
mAge = pAge;
}
public String getName() {
return mName;
}
public int getAge() {
return mAge;
}
public byte[] bytes() {
byte[] bytes = null;
try (ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteOutputStream);) { // Application will break on this line when run on Xcode
objectOutputStream.writeObject(this);
bytes = byteOutputStream.toByteArray();
} catch (IOException ioe) {
System.err.println("Aww snap: " + ioe);
}
return bytes;
}
}
I've unit tested this class in Java (which I also have a deserializer for) and it passes. In Objective-C, I'm doing this:
ComMycompanyTestData *testData = [[ComMycompanyTestData alloc] initWithNSString:#"Daryl" withInt:47];
IOSByteArray *bytes = testData.bytes; // Exception here
The exception is:
(lldb) po $arg1
java.lang.NoSuchMethodException: writeReplace
The relevant trace is:
frame #0: 0x000000019a2cbf48 libobjc.A.dylib`objc_exception_throw
frame #1: 0x0000000100214bb0 MyApp `-[IOSClass getDeclaredMethod:parameterTypes:] + 124
frame #2: 0x00000001000c9188 MyApp`JavaIoObjectStreamClass_findMethodWithIOSClass_withNSString_ + 144
frame #3: 0x00000001000c71dc MyApp`JavaIoObjectStreamClass_createClassDescWithIOSClass_ + 984
frame #4: 0x00000001000c909c MyApp`JavaIoObjectStreamClass_lookupStreamClassWithIOSClass_ + 88
frame #5: 0x00000001000c8f88 MyApp`JavaIoObjectStreamClass_lookupWithIOSClass_ + 44
frame #6: 0x00000001000c6f30 MyApp`JavaIoObjectStreamClass_createClassDescWithIOSClass_ + 300
frame #7: 0x00000001000c909c MyApp`JavaIoObjectStreamClass_lookupStreamClassWithIOSClass_ + 88
frame #8: 0x00000001000c8f88 MyApp`JavaIoObjectStreamClass_lookupWithIOSClass_ + 44
frame #9: 0x00000001000c284c MyApp`JavaIoObjectOutputStream_initWithJavaIoOutputStream_ + 56
frame #10: 0x00000001000c6a20 MyApp`new_JavaIoObjectOutputStream_initWithJavaIoOutputStream_ + 48
* frame #11: 0x00000001000a666c MyApp`-[ComMycompanyTestData bytes](self=0x000000013fd51a50, _cmd="bytes") + 76 at TestData.java:49
Thoughts on what might be happening?
What version of j2objc are you using? We've made recent improvements in serialization, and running your example works after adding this test added:
public static void main(String[] args) {
TestData td = new TestData("Jane Doe", 30);
byte[] serialized = td.bytes();
System.out.println("serialized: " + Arrays.toString(serialized));
}
I ran this with a translator/runtime built using "make dist" on the current j2objc source:
$ javac TestData.java
$ java TestData
serialized: [-84, -19, 0, ...
$ j2objc TestData.java
translating TestData.java
Translated 1 file: 0 errors, 0 warnings
$ j2objcc TestData.m
$ ./a.out TestData
serialized: [-84, -19, 0, ...
Related
I would like to use (Javonet) in .Net and downloded sample from
https://github.com/Javonet/dotnet-devs-samples/tree/master/FirstDotNetConsoleApp
Compiler throws "Initializing JVM failed." exception.
How can i fix?
/// This sample shows how to create instance of Java class, call methods and get/set fields.
static void Main(string[] args)
{
Console.WriteLine("Activating Javonet...");
//You can obtain your free trial key at: https://my.javonet.com/signup/
//Check more at http://www.javonet.com
JavonetBridge.Javonet.Activate("your#mail.com", "your-license-key",
#"C:\Program Files (x86)\Java\jdk1.8.0_144");
JavonetBridge.Javonet.AddReference(#"SampleJavaJar.jar");
//Creating instance of Java class
var sampleClass = JavonetBridge.Javonet.New("SampleJavaClass");
//Calling instance methods
String res = sampleClass.Invoke("SayHello", "Student");
Console.WriteLine("Java method 'SayHello' returned: " + res);
//Setting fields
sampleClass.Set("numberA", 4);
sampleClass.Set("numberB", 8);
//Getting fields
var a = sampleClass.Get("numberA");
Console.WriteLine("Field 'numberA' has value: " + a);
var b = sampleClass.Get("numberB");
Console.WriteLine("Field 'numberB' has value: " + b);
//Calling instance methods with int result
int result = sampleClass.Invoke("SumAandB");
Console.WriteLine("Sum of A and B is: " + result);
//Calling method passing int arguments
int multiplyResult = sampleClass.Invoke("Multiply", 10, 4);
Console.WriteLine("Result of multiplying 10 and 4 is: " + multiplyResult);
Console.WriteLine("\n\nCongratulations! You just called Java from .NET. Easy, isn't it?");
Console.ReadLine();
}
}
}
I downloaded 32 bit jdk1.8.0_291 and problem solved.
How can you use FileHelpers to read Fixed length file with no line breaks or delimiters? Basically, one to many records on a single line. I have to read in a fixed length record with 13 fields totaling 80 characters. If there are 3 records, for example, that would be a single line with 240 characters in it. The answer can't be go to the source and have them output the file differently. They won't budge. I can abandon FileHelpers, but I like how it works and I first want to see if it's possible before I move on. To answer this, you would have to be firmiliar with FileHelpers.
Here is a simple sample like I explained above with 34 records...
var FileContent = "car 2010Ford Mustang Truck2011Chevy S10 Car 2018Toyota Corola SUV 2017Jeep Wrangler ";
[FixedLengthRecord(FixedMode.ExactLength)]
public class dtoCarRecord
{
[FieldFixedLength(5)]
public string Type;
[FieldFixedLength(4)]
public string Year;
[FieldFixedLength(10)]
public string Make;
[FieldFixedLength(15)]
public string Model;
}
void ApplyDateUpdates(object parameter)
{
var raRecords = new List<dtoRARecord>();
var engine = new FileHelperAsyncEngine<dtoRARecord>();
// Read
using (engine.BeginReadFile((string)parameter))
{
// The engine is IEnumerable
foreach (dtoRARecord detail in engine)
{
// your code here
raRecords.Add(detail);
}
}
}
I'm expecting 4 records out of this file.
Just split your file every 80 characters before importing it.
private static string SplitIntoChunks(string text, int maxWidth)
{
var sb = new StringBuilder(text);
for (int i = 1; i < (sb.Length / maxWidth); i++)
{
int insertPosition = i * maxWidth + i - 1;
sb.Insert(insertPosition, "\n");
}
return sb.ToString();
}
var splitIntoChunks = SplitIntoChunks(FileContent, 34);
using (engine.BeginReadString(splitIntoChunks))
{
// The engine is IEnumerable
foreach (dtoRARecord detail in engine)
{
// your code here
raRecords.Add(detail);
}
}
Assert.AreEqual(4, raRecords.Count());
I have a sample hive table created as
CREATE TABLE union_test(foo UNIONTYPE<int, double, array<string>, struct<a:int,b:string>>);
The data can be viewed as
SELECT foo FROM union_test;
The output is
{0:1}
{1:2.0}
{2:["three","four"]}
{3:{"a":5,"b":"five"}}
{2:["six","seven"]}
{3:{"a":8,"b":"eight"}}
{0:9}
{1:10.0}
the first field (tag) denotes the type of the union ( 0 for int, 1 for double, 2 for array etc).
My problem is if I found to select only those records where the union type is 2 (array), how should I frame my query?
There is no function in Hive to read data from UnionType. So i wrote 2 UDF´s. One to get Union tag (that you trying to do) and second to get struct from union as an example.
get_union_tag() function:
package HiveUDF;
import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.UnionObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
#Description(name = "get_union_tag", value = "_FUNC_(unionObject)"
+ " - Returns union object Tag", extended = "Example:\n" + " > SELECT _FUNC_(unionObject) FROM src LIMIT 1;\n one")
public class GetUnionTag extends GenericUDF {
// Global variables that inspect the input.
// These are set up during the initialize() call, and are then used during the
// calls to evaluate()
private transient UnionObjectInspector uoi;
#Override
// This is what we do in the initialize() method:
// Verify that the input is of the type expected
// Set up the ObjectInspectors for the input in global variables
// Return the ObjectInspector for the output
public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
// Verify the input is of the required type.
// Set the global variables (the various ObjectInspectors) while we're doing this
// Exactly one input argument
if( arguments.length != 1 ){
throw new UDFArgumentLengthException("_FUNC_(unionObject) accepts exactly one argument.");
}
// Is the input an array<>
if( arguments[0].getCategory() != ObjectInspector.Category.UNION ){
throw new UDFArgumentTypeException(0,"The single argument to AddExternalIdToPurchaseDetails should be "
+ "Union<>"
+ " but " + arguments[0].getTypeName() + " is found");
}
// Store the ObjectInspectors for use later in the evaluate() method
uoi = ((UnionObjectInspector)arguments[0]);
// Set up the object inspector for the output, and return it
return PrimitiveObjectInspectorFactory.javaByteObjectInspector;
}
#Override
public Object evaluate(DeferredObject[] arguments) throws HiveException {
byte tag = uoi.getTag(arguments[0].get());
return tag;
}
#Override
public String getDisplayString(String[] children) {
StringBuilder sb = new StringBuilder();
sb.append("get_union_tag(");
for (int i = 0; i < children.length; i++) {
if (i > 0) {
sb.append(',');
}
sb.append(children[i]);
}
sb.append(')');
return sb.toString();
}
}
function get_struct_from_union() UDF :
package HiveUDF;
import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.UnionObjectInspector;
#Description(name = "get_union_struct", value = "_FUNC_(unionObject)"
+ " - Returns struct ", extended = "Example:\n" + " > _FUNC_(unionObject).value \n 90.0121")
public class GetUnionStruct extends GenericUDF {
// Global variables that inspect the input.
// These are set up during the initialize() call, and are then used during the
// calls to evaluate()
//
// ObjectInspector for the list (input array<>)
// ObjectInspector for the struct<>
// ObjectInspectors for the elements of the struct<>, target, quantity and price
private UnionObjectInspector unionObjectInspector;
private StructObjectInspector structObjectInspector;
#Override
// This is what we do in the initialize() method:
// Verify that the input is of the type expected
// Set up the ObjectInspectors for the input in global variables
// Return the ObjectInspector for the output
public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
// Verify the input is of the required type.
// Set the global variables (the various ObjectInspectors) while we're doing this
// Exactly one input argument
if( arguments.length != 1 ){
throw new UDFArgumentLengthException("_FUNC_(unionObject) accepts exactly one argument.");
}
// Is the input an array<>
if( arguments[0].getCategory() != ObjectInspector.Category.UNION ){
throw new UDFArgumentTypeException(0,"The single argument to AddExternalIdToPurchaseDetails should be "
+ "Union<Struct>"
+ " but " + arguments[0].getTypeName() + " is found");
}
// Set up the object inspector for the output, and return it
return structObjectInspector;
}
#Override
public Object evaluate(DeferredObject[] arguments) throws HiveException {
return ((UnionObjectInspector) unionObjectInspector).getField(arguments[0].get());
}
#Override
public String getDisplayString(String[] children) {
StringBuilder sb = new StringBuilder();
sb.append("get_union_vqtstruct(");
for (int i = 0; i < children.length; i++) {
if (i > 0) {
sb.append(',');
}
sb.append(children[i]);
}
sb.append(')');
return sb.toString();
}
}
to use these UDF´s compile and create jar file. Than upload into hive (in my case HDInsight). Than just use
add jar wasb:///hive/HiveGUDF.jar;
CREATE TEMPORARY FUNCTION get_union_struct AS 'HiveUDF.GetUnionStruct';
before u run e.g.
SELECT get_union_tag(exposed) FROM test;
I work with the kinect. My goal is to store the values gives me the kinect for the location of the body (head,hand etc). I have written some code but I can not understand what values should save and how.I want to store in the db or in a txt file the position of the head,hands and foots.I want the data to understand the movements of the person who stand in front of kinect.For example if someone move her hand the kinect will sent a value.I must store it and understand and to understand the move taken.Sorry for the few info
here is my code:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Microsoft.Kinect;
using System.Linq;
using System.IO;
namespace KinectSkeletonApplication1
{
public partial class MainWindow : Window
{
//Instantiate the Kinect runtime. Required to initialize the device.
//IMPORTANT NOTE: You can pass the device ID here, in case more than one Kinect device is connected.
KinectSensor sensor = KinectSensor.KinectSensors[0];
byte[] pixelData;
Skeleton[] skeletons;
public MainWindow()
{
InitializeComponent();
///////////////////////////////////
///////////////////////////////
//Runtime initialization is handled when the window is opened. When the window
//is closed, the runtime MUST be unitialized.
this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
this.Unloaded += new RoutedEventHandler(MainWindow_Unloaded);
sensor.ColorStream.Enable();
sensor.SkeletonStream.Enable();
}
void runtime_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
bool receivedData = false;
using (SkeletonFrame SFrame = e.OpenSkeletonFrame())
{
if (SFrame == null)
{
// The image processing took too long. More than 2 frames behind.
}
else
{
skeletons = new Skeleton[SFrame.SkeletonArrayLength];
SFrame.CopySkeletonDataTo(skeletons);
receivedData = true;
}
}
if (receivedData)
{
Skeleton currentSkeleton = (from s in skeletons
where s.TrackingState == SkeletonTrackingState.Tracked
select s).FirstOrDefault();
if (currentSkeleton != null)
{
SetEllipsePosition(head, currentSkeleton.Joints[JointType.Head]);
SetEllipsePosition(leftHand, currentSkeleton.Joints[JointType.HandLeft]);
SetEllipsePosition(rightHand, currentSkeleton.Joints[JointType.HandRight]);
SetEllipsePosition(shoulder_center, currentSkeleton.Joints[JointType.ShoulderCenter]);
}
}
}
//This method is used to position the ellipses on the canvas
//according to correct movements of the tracked joints.
//IMPORTANT NOTE: Code for vector scaling was imported from the Coding4Fun Kinect Toolkit
//available here: http://c4fkinect.codeplex.com/
//I only used this part to avoid adding an extra reference.
private void SetEllipsePosition(Ellipse ellipse, Joint joint)
{
Microsoft.Kinect.SkeletonPoint vector = new Microsoft.Kinect.SkeletonPoint();
vector.X = ScaleVector(640, joint.Position.X);
vector.Y = ScaleVector(480, -joint.Position.Y);
vector.Z = joint.Position.Z;
Joint updatedJoint = new Joint();
updatedJoint = joint;
updatedJoint.TrackingState = JointTrackingState.Tracked;
updatedJoint.Position = vector;
Canvas.SetLeft(ellipse, updatedJoint.Position.X);
Canvas.SetTop(ellipse, updatedJoint.Position.Y);
}
private float ScaleVector(int length, float position)
{
float value = (((((float)length) / 1f) / 2f) * position) + (length / 2);
if (value > length)
{
return (float)length;
}
if (value < 0f)
{
return 0f;
}
string r = Convert.ToString(value);
string path = #"C:\Test\MyTest.txt";
// This text is added only once to the file.
if (!File.Exists(path))
{
// Create a file to write to.
string createText = "Hello and Welcome" + Environment.NewLine;
File.WriteAllText(path, createText);
}
// This text is always added, making the file longer over time
// if it is not deleted.
//string appendText = "This is extra text" + Environment.NewLine;
File.AppendAllText(path, r);
// Open the file to read from.
string readText = File.ReadAllText(path);
return value;
}
void MainWindow_Unloaded(object sender, RoutedEventArgs e)
{
sensor.Stop();
}
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
sensor.SkeletonFrameReady += runtime_SkeletonFrameReady;
sensor.ColorFrameReady += runtime_VideoFrameReady;
sensor.Start();
}
void runtime_VideoFrameReady(object sender, ColorImageFrameReadyEventArgs e)
{
bool receivedData = false;
using (ColorImageFrame CFrame = e.OpenColorImageFrame())
{
if (CFrame == null)
{
// The image processing took too long. More than 2 frames behind.
}
else
{
pixelData = new byte[CFrame.PixelDataLength];
CFrame.CopyPixelDataTo(pixelData);
receivedData = true;
}
}
if (receivedData)
{
BitmapSource source = BitmapSource.Create(640, 480, 96, 96,
PixelFormats.Bgr32, null, pixelData, 640 * 4);
videoImage.Source = source;
}
}
}
}
I think what you are looking for is getting the X, Y, Z coordiantes for certain Joints?
In this case add this code:
Vector3D ShoulderCenter = new Vector3D(skeleton.Joints[JointType.ShoulderCenter].Position.X, skeleton.Joints[JointType.ShoulderCenter].Position.Y, skeleton.Joints[JointType.ShoulderCenter].Position.Z);
Vector3D RightShoulder = new Vector3D(skeleton.Joints[JointType.ShoulderRight].Position.X, skeleton.Joints[JointType.ShoulderRight].Position.Y, skeleton.Joints[JointType.ShoulderRight].Position.Z);
Vector3D LeftShoulder = new Vector3D(skeleton.Joints[JointType.ShoulderLeft].Position.X, skeleton.Joints[JointType.ShoulderLeft].Position.Y, skeleton.Joints[JointType.ShoulderLeft].Position.Z);
Vector3D RightElbow = new Vector3D(skeleton.Joints[JointType.ElbowRight].Position.X, skeleton.Joints[JointType.ElbowRight].Position.Y, skeleton.Joints[JointType.ElbowRight].Position.Z);
Vector3D LeftElbow = new Vector3D(skeleton.Joints[JointType.ElbowLeft].Position.X, skeleton.Joints[JointType.ElbowLeft].Position.Y, skeleton.Joints[JointType.ElbowLeft].Position.Z);
Vector3D RightWrist = new Vector3D(skeleton.Joints[JointType.WristRight].Position.X, skeleton.Joints[JointType.WristRight].Position.Y, skeleton.Joints[JointType.WristRight].Position.Z);
Vector3D LeftWrist = new Vector3D(skeleton.Joints[JointType.WristLeft].Position.X, skeleton.Joints[JointType.WristLeft].Position.Y, skeleton.Joints[JointType.WristLeft].Position.Z);
This only defines the Vectors for the upper Body part as you can see. Just add the missing joints the way I did it.
You need following assemblies:
using System.Windows.Media;
using Microsoft.Kinect.Toolkit.Fusion;
using System.Windows.Media.Media3D;
I have a GPS tracker with TK06a Chipset, and I have my own tcp listener, everything is working fine, I have received the data from the device with this format :
#355488020131775##1#0000#AUT#01#52500100232a47#10341.175280,E,121.322800,N,0.28,0.00#111113#171607.000##
I think i figured out what are these, (for example the first one is the IMEI), but I didn't know how to convert (10341.175280,E) and (121.322800,N) to something that google maps can understand.
beside the device has a poor user manual and no documentation for the protocol.
the real location should be in here (1.355269,103.686426) maybe this can lead you to solve this mystery :)
Thanks in advance.
Edit:
I Found this on the web, maybe some will find it useful :
The decode of the line above.
the IMEI number cannot be empty, if the SIM card number regarded as device series number, then the data of IMEI part should be filled in
SIM cad number.
SIM card number: this part can be empty , or also can be same as 1st point , fill in SIM card number.
0 or 1 , reserve (original meaning is ACC status )
Device password ( 0-9 numbers, digit cannot over 6 digits, generally is in 4 digits )
Reserved word AUT, cannot be changed .
Numbers of data, 00-99 , in 2 digits.
The format of Each data as below:
#base station number#Longitude, East and West identification, latitude,North and South identification,speed(nm), direction angle(0-360)#date#time
Base station number can be empty.
Longitude, format : dddff.ffff, the degree part must be in 3 integer, the minute part must be in 2 integer, the decimal part is in
4 digits, there is no separator between degree and minute.
East and West identification, only one character , E/W.
Latitude, format : ddff.ffff, same as Longitude , only the degree part is in 2 integer.
North and South identification, only one character , N/S.
Speed: can be 0.
Direction : can be 0.
Date, format : ddmmyy.
Time, format: hhnnss.mmm, the part before decimal point should be hour, minute and second in turn, each is in 2 digits, the part after
decimal point should be milliseconds, it can be 000.
This format is DM like in NMEA RMC message, but with a missing leading 0:
given longitude: 10341.175280 E
The first 3 digits are degrees: 103
Then the rest is minutes: 41.175280
This now is fomrat "DM" Degrees and decimal minutes.
Google uses "DEG" (Decimal degrees)
convert: 103 + 41.175280 / 60.0 = 103.686254
(DEG = degrees + minutes / 60.0)
wich fits perfectly to your location
Now it is a bit strange:
It should read "0121.322800" not "121.322800"
But then similar to above but since latitude is limited to two digits:
The first 2 digits are always degrees: 01
Then the rest is minutes: 21.322800
same formala as above: lat= 1 + 21.322800 / 60.0 = 1,35538
finally: if W or S, multiply the deg value with -1
(In your case it is N and E, so it stays as it is - positive)
This format looks partly like the NMEA RMC sentence
I think you want to make this work with OpenGTS.
So here what i done to work:(Note i dont need the tk10x devices so i overwrited the files, you can create another class if you want)
go to $GTS_HOME/src/org/opengts/servers/tk10x
and change the TrackServer.java with this code
I writed a new parseInsertFunction
package org.opengts.servers.tk10x;
import java.lang.*;
import java.util.*;
import java.io.*;
import java.net.*;
import java.sql.*;
import org.opengts.util.*;
import org.opengts.db.*;
import org.opengts.db.tables.*;
public class TrackServer
{
// ------------------------------------------------------------------------
// initialize runtime configuration
public static void configInit()
{
DCServerConfig dcs = Main.getServerConfig();
if (dcs != null) {
TrackServer.setTcpIdleTimeout( dcs.getTcpIdleTimeoutMS( Constants.TIMEOUT_TCP_IDLE ));
TrackServer.setTcpPacketTimeout( dcs.getTcpPacketTimeoutMS( Constants.TIMEOUT_TCP_PACKET ));
TrackServer.setTcpSessionTimeout(dcs.getTcpSessionTimeoutMS(Constants.TIMEOUT_TCP_SESSION));
TrackServer.setUdpIdleTimeout( dcs.getUdpIdleTimeoutMS( Constants.TIMEOUT_UDP_IDLE ));
TrackServer.setUdpPacketTimeout( dcs.getUdpPacketTimeoutMS( Constants.TIMEOUT_UDP_PACKET ));
TrackServer.setUdpSessionTimeout(dcs.getUdpSessionTimeoutMS(Constants.TIMEOUT_UDP_SESSION));
}
}
// ------------------------------------------------------------------------
// Start TrackServer (TrackServer is a singleton)
private static TrackServer trackServerInstance = null;
/* start TrackServer on array of ports */
public static TrackServer startTrackServer(int tcpPorts[], int udpPorts[], int commandPort)
throws Throwable
{
if (trackServerInstance == null) {
trackServerInstance = new TrackServer(tcpPorts, udpPorts, commandPort);
} else {
//Print.logError("TrackServer already initialized!");
}
return trackServerInstance;
}
public static TrackServer getTrackServer()
{
return trackServerInstance;
}
// ------------------------------------------------------------------------
// TCP Session timeouts
/* idle timeout */
private static long tcpTimeout_idle = Constants.TIMEOUT_TCP_IDLE;
public static void setTcpIdleTimeout(long timeout)
{
TrackServer.tcpTimeout_idle = timeout;
}
public static long getTcpIdleTimeout()
{
return TrackServer.tcpTimeout_idle;
}
/* inter-packet timeout */
private static long tcpTimeout_packet = Constants.TIMEOUT_TCP_PACKET;
public static void setTcpPacketTimeout(long timeout)
{
TrackServer.tcpTimeout_packet = timeout;
}
public static long getTcpPacketTimeout()
{
return TrackServer.tcpTimeout_packet;
}
/* total session timeout */
private static long tcpTimeout_session = Constants.TIMEOUT_TCP_SESSION;
public static void setTcpSessionTimeout(long timeout)
{
TrackServer.tcpTimeout_session = timeout;
}
public static long getTcpSessionTimeout()
{
return TrackServer.tcpTimeout_session;
}
// ------------------------------------------------------------------------
// UDP Session timeouts
/* idle timeout */
private static long udpTimeout_idle = Constants.TIMEOUT_UDP_IDLE;
public static void setUdpIdleTimeout(long timeout)
{
TrackServer.udpTimeout_idle = timeout;
}
public static long getUdpIdleTimeout()
{
return TrackServer.udpTimeout_idle;
}
/* inter-packet timeout */
private static long udpTimeout_packet = Constants.TIMEOUT_UDP_PACKET;
public static void setUdpPacketTimeout(long timeout)
{
TrackServer.udpTimeout_packet = timeout;
}
public static long getUdpPacketTimeout()
{
return TrackServer.udpTimeout_packet;
}
/* total session timeout */
private static long udpTimeout_session = Constants.TIMEOUT_UDP_SESSION;
public static void setUdpSessionTimeout(long timeout)
{
TrackServer.udpTimeout_session = timeout;
}
public static long getUdpSessionTimeout()
{
return TrackServer.udpTimeout_session;
}
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// TCP port listener threads
private java.util.List<ServerSocketThread> tcpThread = new Vector<ServerSocketThread>();
// UDP port listener threads
private java.util.List<ServerSocketThread> udpThread = new Vector<ServerSocketThread>();
// Command port listener thread
private ServerSocketThread cmdThread = null;
private DatagramSocket udpSocket = null;
// ------------------------------------------------------------------------
/* private constructor */
private TrackServer(int tcpPorts[], int udpPorts[], int commandPort)
throws Throwable
{
int listeners = 0;
// Start TCP listeners
if (!ListTools.isEmpty(tcpPorts)) {
for (int i = 0; i < tcpPorts.length; i++) {
int port = tcpPorts[i];
if (ServerSocketThread.isValidPort(port)) {
try {
this._startTCP(port);
listeners++;
} catch (java.net.BindException be) {
Print.logError("TCP: Error binding to port: %d", port);
}
} else {
throw new Exception("TCP: Invalid port number: " + port);
}
}
}
// Start UDP listeners
if (!ListTools.isEmpty(udpPorts)) {
for (int i = 0; i < udpPorts.length; i++) {
int port = udpPorts[i];
if (ServerSocketThread.isValidPort(port)) {
try {
ServerSocketThread sst = this._startUDP(port);
if (this.udpSocket == null) {
this.udpSocket = sst.getDatagramSocket();
}
listeners++;
} catch (java.net.BindException be) {
Print.logError("UDP: Error binding to port: %d", port);
}
} else {
throw new Exception("UDP: Invalid port number: " + port);
}
}
}
/* do we have any active listeners? */
if (listeners <= 0) {
Print.logWarn("No active device communication listeners!");
}
}
// ------------------------------------------------------------------------
/* start TCP listener */
private void _startTCP(int port)
throws Throwable
{
ServerSocketThread sst = null;
/* create server socket */
try {
sst = new ServerSocketThread(port);
} catch (Throwable t) { // trap any server exception
Print.logException("ServerSocket error", t);
throw t;
}
/* initialize */
sst.setTextPackets(Constants.ASCII_PACKETS);
sst.setBackspaceChar(null); // no backspaces allowed
sst.setLineTerminatorChar(Constants.ASCII_LINE_TERMINATOR);
sst.setIgnoreChar(Constants.ASCII_IGNORE_CHARS);
sst.setMaximumPacketLength(Constants.MAX_PACKET_LENGTH);
sst.setMinimumPacketLength(Constants.MIN_PACKET_LENGTH);
sst.setIdleTimeout(TrackServer.tcpTimeout_idle); // time between packets
sst.setPacketTimeout(TrackServer.tcpTimeout_packet); // time from start of packet to packet completion
sst.setSessionTimeout(TrackServer.tcpTimeout_session); // time for entire session
sst.setTerminateOnTimeout(Constants.TERMINATE_ON_TIMEOUT);
sst.setClientPacketHandlerClass(TrackClientPacketHandler.class);
sst.setLingerTimeoutSec(Constants.LINGER_ON_CLOSE_SEC);
/* start thread */
Print.logInfo("Starting TCP listener thread on port " + port + " [timeout=" + sst.getSessionTimeout() + "ms] ...");
sst.start();
this.tcpThread.add(sst);
}
// ------------------------------------------------------------------------
/* start UDP listener */
private ServerSocketThread _startUDP(int port)
throws Throwable
{
ServerSocketThread sst = null;
/* create server socket */
try {
sst = new ServerSocketThread(ServerSocketThread.createDatagramSocket(port));
} catch (Throwable t) { // trap any server exception
Print.logException("ServerSocket error", t);
throw t;
}
/* initialize */
sst.setTextPackets(Constants.ASCII_PACKETS);
sst.setBackspaceChar(null); // no backspaces allowed
sst.setLineTerminatorChar(Constants.ASCII_LINE_TERMINATOR);
sst.setIgnoreChar(Constants.ASCII_IGNORE_CHARS);
sst.setMaximumPacketLength(Constants.MAX_PACKET_LENGTH);
sst.setMinimumPacketLength(Constants.MIN_PACKET_LENGTH);
sst.setIdleTimeout(TrackServer.udpTimeout_idle);
sst.setPacketTimeout(TrackServer.udpTimeout_packet);
sst.setSessionTimeout(TrackServer.udpTimeout_session);
sst.setTerminateOnTimeout(Constants.TERMINATE_ON_TIMEOUT);
sst.setClientPacketHandlerClass(TrackClientPacketHandler.class);
/* start thread */
Print.logInfo("Starting UDP listener thread on port " + port + " [timeout=" + sst.getSessionTimeout() + "ms] ...");
sst.start();
this.udpThread.add(sst);
return sst;
}
public DatagramSocket getUdpDatagramSocket()
{
return this.udpSocket;
}
// ------------------------------------------------------------------------
}`
and in Constant.java find 'ASCII_LINE_TERMINATOR[] ' constant declaration and add '000' to with
public static final int ASCII_LINE_TERMINATOR[] = new int[] {
// this list has been construction by observation of various data packets
0x00, 0xFF, 0xCE, '\0', '\n', '\r', ')', ';',000
};
after this
cd $GTS_HOME
ant tk10x
bin/runserver.sh -s tk10x
This should do the trick
And here is a link to the package i created
https://anonfiles.com/file/0aae22ccb3822618fb693cd667283b18