Hi All,
Over the last couple of weeks, I spent some time trying to generate Comm Effect
events from Java (as opposed to Python). I thought I would post my results
here, in case it would be of help to anyone else.
If someone has a better approach (or finds that I was not doing something the
way I should have been), please let me know.
Down the road, we will be using a similar approach to generate other events as
well from Java code in order to drive the behavior of EMANE.
The first step was to generate the Java source from the .proto files that were
in the libemane directory. One problem was that it could not generate the .java
file for event.proto because of a conflict in the class name. So, we had to
edit Event.proto and add the following option:
option java_outer_classname="BasicEvent";
This should probably be fixed in the event.proto file.
Then, I combined all the generated Java code into a single JAR file. The
following Java code uses that JAR file to generate and send events that are
equivalent to the following command:
emaneevent-commeffect 1:4 –t 1 latency=.5
Here is my code which sends a single commeffect to all nodes 2:4 indicating a
500 msec latency value to apply to all packets received from NEM 1.
There are a couple of places that I had to do things that I was not expecting
to. The first case is that the type of the event (CommEffectEvent), identified
by the id 103, had to be set manually into the BasicEvent instance.
The second case is that I had to compute the length of the serialized event and
prefix the byte array being transmitted over the network with this length.
Again, something that I would have expected to be done automatically.
Some of this had to be done by reverse engineering the network packet generated
by the emaneevent-commeffect command, and it took me a while to do it. If there
are better ways to do what I have done, please let me know. Perhaps some
additional documentation would be useful. And, I hope this example would be
useful to others as well.
Thanks.
Maggie
______________________________________________________________________
// CommEffectEvent builder
Commeffectevent.CommEffectEvent.Builder commEffectEventBuilder =
Commeffectevent.CommEffectEvent.newBuilder();
for (int id=2; id<=4; id++) {
Commeffectevent.CommEffectEvent.CommEffect.Builder commEffectBuilder =
Commeffectevent.CommEffectEvent.CommEffect.newBuilder();
commEffectBuilder.setLatencySeconds(0.5f);
commEffectBuilder.setNemId(id);
commEffectBuilder.setJitterSeconds(0);
commEffectBuilder.setBroadcastBitRatebps(0);
commEffectBuilder.setProbabilityDuplicate(0);
commEffectBuilder.setUnicastBitRatebps(0);
commEffectBuilder.setProbabilityLoss(0);
//Need to add the commEffect to the event builder as a list
commEffectEventBuilder.addCommEffects(commEffectBuilder);
}
ByteString commEffectEventBA = commEffectEventBuilder.build().toByteString();
// Serialization builder
EMANEMessage.BasicEvent.Event.Data.Serialization.Builder serialBuilder =
BasicEvent.Event.Data.Serialization.newBuilder();
serialBuilder.setNemId (1);
serialBuilder.setEventId (103); // This should be done automatically, but I had
to hard code it
serialBuilder.setData (commEffectEventBA);
serialBuilder.build();
//Basic event builder
EMANEMessage.BasicEvent.Event.Builder evtBuilder =
EMANEMessage.BasicEvent.Event.newBuilder();
// Generate a random uuid of 16 bytes – probably a better way to do this
byte[] randomUUIDByteArray = new byte[16];
Random randomGenerator = new Random();
for (int i=0; i<16; i++) {
int randomInt = randomGenerator.nextInt(100);
ByteBuffer bb = ByteBuffer.wrap (randomUUIDByteArray);
bb.putInt (randomInt);
}
ByteString uuidByteStr = ByteString.copyFrom (randomUUIDByteArray);
evtBuilder.setUuid (uuidByteStr);
evtBuilder.setSequenceNumber (1);
BasicEvent.Event.Data.Builder dataBuilder = BasicEvent.Event.Data.newBuilder();
dataBuilder.addSerializations (serialBuilder);
BasicEvent.Event.Data data = dataBuilder.build();
//Set data in the Basic event.
byte[] fullDataByteArray = evtBuilder.setData (data).build().toByteArray();
// The following code compute the length of the event and prepends the network
packet with 2 bytes
// containing that length. Again, this probably should be done automatically
int arrayLen = fullDataByteArray.length;
byte[] newbuf = new byte [fullDataByteArray.length + 2];
ByteBuffer bb = ByteBuffer.wrap (newbuf);
bb.putShort ((short) arrayLen);
bb.put (fullDataByteArray);
while (true) {
MulticastSocket mcs = new MulticastSocket();
InetAddress group = InetAddress.getByName ("224.1.2.8");
mcs.joinGroup (group);
DatagramPacket dp = new DatagramPacket (newbuf, newbuf.length, group,
45703);
System.err.print("..");
mcs.send (dp);
Thread.sleep (1000);
}
_______________________________________________________
---------------------------------------------------------------------
Maggie R. Breedy
Research Associate
Florida Institute for Human and Machine Cognition
Pensacola, FL.
_______________________________________________
emane-users mailing list
[email protected]
http://pf.itd.nrl.navy.mil/mailman/listinfo/emane-users