From 7ee2fadfa3587277f7d1df43f333d49876f1d657 Mon Sep 17 00:00:00 2001 From: niccellular <79813408+niccellular@users.noreply.github.com> Date: Sat, 10 Feb 2024 16:37:55 -0500 Subject: [PATCH] 1.0.5 - new protobufs for geochat/pli wire optimized protobufs for pli/chat --- .../meshtastic/MeshtasticMapComponent.java | 101 ++++++++++++++- .../meshtastic/MeshtasticReceiver.java | 117 +++++++++++++++--- 2 files changed, 195 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/com/atakmap/android/meshtastic/MeshtasticMapComponent.java b/app/src/main/java/com/atakmap/android/meshtastic/MeshtasticMapComponent.java index 6015622..88df796 100644 --- a/app/src/main/java/com/atakmap/android/meshtastic/MeshtasticMapComponent.java +++ b/app/src/main/java/com/atakmap/android/meshtastic/MeshtasticMapComponent.java @@ -8,7 +8,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; -import android.os.Environment; + import android.os.IBinder; import android.os.RemoteException; import android.widget.Toast; @@ -119,6 +119,10 @@ public static List divideArray(byte[] source, int chunksize) { @Override public void processCotEvent(CotEvent cotEvent, String[] strings) { + Log.d(TAG, "callsign: " + getMapView().getDeviceCallsign()); + Log.d(TAG, "device callsign: " + getMapView().getSelfMarker().getUID()); + + if (mConnectionState == ServiceConnectionState.DISCONNECTED) return; @@ -132,7 +136,8 @@ public void processCotEvent(CotEvent cotEvent, String[] strings) { double divisor = 1e-7; XmlPullParserFactory factory = null; XmlPullParser xpp = null; - String callsign = getMapView().getDeviceCallsign(); + String callsign = null; + String deviceCallsign = null; double alt = getMapView().getSelfMarker().getPoint().getAltitude(); double lat = getMapView().getSelfMarker().getPoint().getLatitude(); double lng = getMapView().getSelfMarker().getPoint().getLongitude(); @@ -176,14 +181,14 @@ public void processCotEvent(CotEvent cotEvent, String[] strings) { if (eventType == XmlPullParser.START_TAG) { if (xpp.getName().equalsIgnoreCase("contact")) { int attributeCount = xpp.getAttributeCount(); - Log.d(TAG, "Contact has " + +attributeCount); + Log.d(TAG, "Contact has " + attributeCount); for (int i = 0; i < attributeCount; i++) { if (xpp.getAttributeName(i).equalsIgnoreCase("callsign")) callsign = xpp.getAttributeValue(i); } } else if (xpp.getName().equalsIgnoreCase("__group")) { int attributeCount = xpp.getAttributeCount(); - Log.d(TAG, "__group has " + +attributeCount); + Log.d(TAG, "__group has " + attributeCount); for (int i = 0; i < attributeCount; i++) { if (xpp.getAttributeName(i).equalsIgnoreCase("role")) role = xpp.getAttributeValue(i); @@ -192,14 +197,14 @@ else if (xpp.getAttributeName(i).equalsIgnoreCase("name")) } } else if (xpp.getName().equalsIgnoreCase("status")) { int attributeCount = xpp.getAttributeCount(); - Log.d(TAG, "status has " + +attributeCount); + Log.d(TAG, "status has " + attributeCount); for (int i = 0; i < attributeCount; i++) { if (xpp.getAttributeName(i).equalsIgnoreCase("battery")) battery = Integer.parseInt(xpp.getAttributeValue(i)); } } else if (xpp.getName().equalsIgnoreCase("track")) { int attributeCount = xpp.getAttributeCount(); - Log.d(TAG, "track has " + +attributeCount); + Log.d(TAG, "track has " + attributeCount); for (int i = 0; i < attributeCount; i++) { if (xpp.getAttributeName(i).equalsIgnoreCase("course")) course = Double.valueOf(xpp.getAttributeValue(i)).intValue(); @@ -216,6 +221,7 @@ else if (xpp.getAttributeName(i).equalsIgnoreCase("speed")) ATAKProtos.Contact.Builder contact = ATAKProtos.Contact.newBuilder(); contact.setCallsign(callsign); + contact.setDeviceCallsign(cotEvent.getUID()); ATAKProtos.Group.Builder group = ATAKProtos.Group.newBuilder(); group.setRole(ATAKProtos.MemberRole.valueOf(role.replace(" ", ""))); @@ -238,6 +244,7 @@ else if (xpp.getAttributeName(i).equalsIgnoreCase("speed")) tak_packet.setPli(pli); Log.d(TAG, "Total wire size for TAKPacket: " + tak_packet.build().toByteArray().length); + Log.d(TAG, "Sending: " + tak_packet.build().toString()); dp = new DataPacket("^all", tak_packet.build().toByteArray(), Portnums.PortNum.ATAK_PLUGIN_VALUE, DataPacket.ID_LOCAL, System.currentTimeMillis(), 0, MessageStatus.UNKNOWN, 3, 0); try { @@ -277,6 +284,85 @@ else if (xpp.getAttributeName(i).equalsIgnoreCase("speed")) if (xpp.getAttributeName(i).equalsIgnoreCase("senderCallsign")) callsign = xpp.getAttributeValue(i); } + } else if (xpp.getName().equalsIgnoreCase("link")) { + int attributeCount = xpp.getAttributeCount(); + Log.d(TAG, "link has " + +attributeCount); + for (int i = 0; i < attributeCount; i++) { + if (xpp.getAttributeName(i).equalsIgnoreCase("uid")) + deviceCallsign = xpp.getAttributeValue(i); + } + } + } + eventType = xpp.next(); + } + + } catch (XmlPullParserException | IOException e) { + e.printStackTrace(); + } + + ATAKProtos.Contact.Builder contact = ATAKProtos.Contact.newBuilder(); + contact.setCallsign(callsign); + contact.setDeviceCallsign(deviceCallsign); + + ATAKProtos.GeoChat.Builder geochat = ATAKProtos.GeoChat.newBuilder(); + geochat.setMessage(message); + geochat.setTo("All Chat Rooms"); + + ATAKProtos.TAKPacket.Builder tak_packet = ATAKProtos.TAKPacket.newBuilder(); + tak_packet.setContact(contact); + tak_packet.setChat(geochat); + + Log.d(TAG, "Total wire size for TAKPacket: " + tak_packet.build().toByteArray().length); + Log.d(TAG, "Sending: " + tak_packet.build().toString()); + + dp = new DataPacket("^all", tak_packet.build().toByteArray(), Portnums.PortNum.ATAK_PLUGIN_VALUE, DataPacket.ID_LOCAL, System.currentTimeMillis(), 0, MessageStatus.UNKNOWN, 3, 0); + try { + mMeshService.send(dp); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + + } else if (cotEvent.getType().equalsIgnoreCase("b-t-f")) { + Log.d(TAG, "DM Chat"); + /* + + + + + <__chat parent='RootContactGroup' groupOwner='false' messageId='23c1f487-7111-4995-89f5-7709a9c99518' chatroom='HUSKER lol' id='ANDROID-b5c2b8340a0a2cd5' senderCallsign='FALKE lol'> + + + + <__serverdestination destinations='0.0.0.0:4242:tcp:ANDROID-e612f0e922b56a63'/> + at breach + + + */ + String message = null; + String to = null; + try { + while (eventType != XmlPullParser.END_DOCUMENT) { + if (eventType == XmlPullParser.START_TAG) { + Log.d(TAG, xpp.getName()); + if (xpp.getName().equalsIgnoreCase("remarks")) { + if (xpp.next() == XmlPullParser.TEXT) + message = xpp.getText(); + } else if (xpp.getName().equalsIgnoreCase("__chat")) { + int attributeCount = xpp.getAttributeCount(); + Log.d(TAG, "__chat has " + +attributeCount); + for (int i = 0; i < attributeCount; i++) { + if (xpp.getAttributeName(i).equalsIgnoreCase("senderCallsign")) + callsign = xpp.getAttributeValue(i); + if (xpp.getAttributeName(i).equalsIgnoreCase("id")) + to = xpp.getAttributeValue(i); + } + } else if (xpp.getName().equalsIgnoreCase("link")) { + int attributeCount = xpp.getAttributeCount(); + Log.d(TAG, "link has " + +attributeCount); + for (int i = 0; i < attributeCount; i++) { + if (xpp.getAttributeName(i).equalsIgnoreCase("uid")) + deviceCallsign = xpp.getAttributeValue(i); + } } } eventType = xpp.next(); @@ -288,15 +374,18 @@ else if (xpp.getAttributeName(i).equalsIgnoreCase("speed")) ATAKProtos.Contact.Builder contact = ATAKProtos.Contact.newBuilder(); contact.setCallsign(callsign); + contact.setDeviceCallsign(deviceCallsign); ATAKProtos.GeoChat.Builder geochat = ATAKProtos.GeoChat.newBuilder(); geochat.setMessage(message); + geochat.setTo(to); ATAKProtos.TAKPacket.Builder tak_packet = ATAKProtos.TAKPacket.newBuilder(); tak_packet.setContact(contact); tak_packet.setChat(geochat); Log.d(TAG, "Total wire size for TAKPacket: " + tak_packet.build().toByteArray().length); + Log.d(TAG, "Sending: " + tak_packet.build().toString()); dp = new DataPacket("^all", tak_packet.build().toByteArray(), Portnums.PortNum.ATAK_PLUGIN_VALUE, DataPacket.ID_LOCAL, System.currentTimeMillis(), 0, MessageStatus.UNKNOWN, 3, 0); try { diff --git a/app/src/main/java/com/atakmap/android/meshtastic/MeshtasticReceiver.java b/app/src/main/java/com/atakmap/android/meshtastic/MeshtasticReceiver.java index 90b76de..5a0e0c7 100644 --- a/app/src/main/java/com/atakmap/android/meshtastic/MeshtasticReceiver.java +++ b/app/src/main/java/com/atakmap/android/meshtastic/MeshtasticReceiver.java @@ -3,13 +3,8 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import android.os.Parcel; -import android.os.RemoteException; -import android.util.Xml; -import com.atakmap.android.chat.GeoChatService; -import com.atakmap.android.contact.Contacts; -import com.atakmap.android.contact.IndividualContact; +import android.os.RemoteException; import com.atakmap.android.cot.CotMapComponent; import com.atakmap.android.maps.MapView; import com.atakmap.coremap.cot.event.CotDetail; @@ -166,9 +161,17 @@ protected void receive(Intent intent) { } } else if (dataType == 72) { Log.d(TAG, "Got TAK_PACKET"); + Log.d(TAG, "Payload: " + payload); + String t = ""; + for (int i=0; i */ - } else if (tp.hasChat()) { - Log.d(TAG, "TAK_PACKET GEOCHAT"); + } else if (tp.hasChat() && tp.getChat().getTo().equals("All Chat Rooms")) { + Log.d(TAG, "TAK_PACKET GEOCHAT - All Chat Rooms"); ATAKProtos.Contact contact = tp.getContact(); ATAKProtos.GeoChat geoChat = tp.getChat(); String callsign = contact.getCallsign(); - String value = String.valueOf(UUID.nameUUIDFromBytes(callsign.getBytes())); + String deviceCallsign = contact.getDeviceCallsign(); String msgId = String.valueOf(UUID.randomUUID()); CotDetail cotDetail = new CotDetail("detail"); @@ -271,13 +275,13 @@ protected void receive(Intent intent) { cotDetail.addChild(chatDetail); CotDetail chatgrp = new CotDetail("chatgrp"); - chatgrp.setAttribute("uid0", value); + chatgrp.setAttribute("uid0", deviceCallsign); chatgrp.setAttribute("uid1", "All Chat Rooms"); chatgrp.setAttribute("id", "All Chat Rooms"); chatDetail.addChild(chatgrp); CotDetail linkDetail = new CotDetail("link"); - linkDetail.setAttribute("uid", value); + linkDetail.setAttribute("uid", deviceCallsign); linkDetail.setAttribute("type", "a-f-G-U-C"); linkDetail.setAttribute("relation", "p-p"); cotDetail.addChild(linkDetail); @@ -287,7 +291,7 @@ protected void receive(Intent intent) { cotDetail.addChild(serverDestinationDetail); CotDetail remarksDetail = new CotDetail("remarks"); - remarksDetail.setAttribute("source", String.format("BAO.F.ATAK.%s", value)); + remarksDetail.setAttribute("source", String.format("BAO.F.ATAK.%s", deviceCallsign)); remarksDetail.setAttribute("to", "All Chat Rooms"); remarksDetail.setAttribute("time", time.toString()); remarksDetail.setInnerText(geoChat.getMessage()); @@ -295,7 +299,7 @@ protected void receive(Intent intent) { CotEvent cotEvent = new CotEvent(); cotEvent.setDetail(cotDetail); - cotEvent.setUID("GeoChat." + value + ".All Chat Rooms." + msgId); + cotEvent.setUID("GeoChat." + deviceCallsign + ".All Chat Rooms." + msgId); cotEvent.setTime(time); cotEvent.setStart(time); cotEvent.setStale(time.addMinutes(10)); @@ -311,6 +315,85 @@ protected void receive(Intent intent) { else Log.e(TAG, "cotEvent was not valid"); + } else if (tp.hasChat() && tp.getChat().getTo().equals(MapView.getMapView().getSelfMarker().getUID())) { + /* + + + + + <__chat parent='RootContactGroup' groupOwner='false' messageId='23c1f487-7111-4995-89f5-7709a9c99518' chatroom='HUSKER lol' id='ANDROID-b5c2b8340a0a2cd5' senderCallsign='FALKE lol'> + + + + <__serverdestination destinations='0.0.0.0:4242:tcp:ANDROID-e612f0e922b56a63'/> + at breach + + + */ + + Log.d(TAG, "TAK_PACKET GEOCHAT - DM"); + + ATAKProtos.Contact contact = tp.getContact(); + ATAKProtos.GeoChat geoChat = tp.getChat(); + + String callsign = contact.getCallsign(); + String deviceCallsign = contact.getDeviceCallsign(); + String msgId = String.valueOf(UUID.randomUUID()); + String to = geoChat.getTo(); + + CotDetail cotDetail = new CotDetail("detail"); + + CoordinatedTime time = new CoordinatedTime(); + + CotDetail chatDetail = new CotDetail("__chat"); + chatDetail.setAttribute("parent", "RootContactGroup"); + chatDetail.setAttribute("groupOwner", "false"); + chatDetail.setAttribute("messageId", msgId); + chatDetail.setAttribute("chatroom", MapView.getMapView().getDeviceCallsign()); + chatDetail.setAttribute("id", MapView.getMapView().getSelfMarker().getUID()); + chatDetail.setAttribute("senderCallsign", callsign); + cotDetail.addChild(chatDetail); + + CotDetail chatgrp = new CotDetail("chatgrp"); + chatgrp.setAttribute("uid0", deviceCallsign); + chatgrp.setAttribute("uid1", MapView.getMapView().getSelfMarker().getUID()); + chatgrp.setAttribute("id", MapView.getMapView().getSelfMarker().getUID()); + chatDetail.addChild(chatgrp); + + CotDetail linkDetail = new CotDetail("link"); + linkDetail.setAttribute("uid", deviceCallsign); + linkDetail.setAttribute("type", "a-f-G-U-C"); + linkDetail.setAttribute("relation", "p-p"); + cotDetail.addChild(linkDetail); + + CotDetail serverDestinationDetail = new CotDetail("__serverdestination"); + serverDestinationDetail.setAttribute("destination", "*:-1:tcp"); + cotDetail.addChild(serverDestinationDetail); + + CotDetail remarksDetail = new CotDetail("remarks"); + remarksDetail.setAttribute("source", String.format("BAO.F.ATAK.%s", deviceCallsign)); + remarksDetail.setAttribute("to", to); + remarksDetail.setAttribute("time", time.toString()); + remarksDetail.setInnerText(geoChat.getMessage()); + cotDetail.addChild(remarksDetail); + + CotEvent cotEvent = new CotEvent(); + cotEvent.setDetail(cotDetail); + cotEvent.setUID("GeoChat." + deviceCallsign + MapView.getMapView().getSelfMarker().getUID() + msgId); + cotEvent.setTime(time); + cotEvent.setStart(time); + cotEvent.setStale(time.addMinutes(10)); + cotEvent.setType("b-t-f"); + cotEvent.setHow("h-g-i-g-o"); + + CotPoint cotPoint = new CotPoint(0, 0, CotPoint.UNKNOWN, + CotPoint.UNKNOWN, CotPoint.UNKNOWN); + cotEvent.setPoint(cotPoint); + + if (cotEvent.isValid()) + CotMapComponent.getInternalDispatcher().dispatch(cotEvent); + else + Log.e(TAG, "cotEvent was not valid"); } } catch (InvalidProtocolBufferException e) {