Skip to content

Commit

Permalink
Refactored chunking
Browse files Browse the repository at this point in the history
Better chunking
  • Loading branch information
niccellular committed Aug 10, 2023
1 parent fd50343 commit d54db55
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,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.provider.ContactsContract;
Expand All @@ -27,10 +28,15 @@
import com.paulmandal.atak.libcotshrink.pub.api.CotShrinker;
import com.paulmandal.atak.libcotshrink.pub.api.CotShrinkerFactory;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.zip.Deflater;
import java.util.zip.GZIPOutputStream;

public class MeshtasticMapComponent extends DropDownMapComponent implements CommsMapComponent.PreSendProcessor {

Expand Down Expand Up @@ -106,7 +112,9 @@ public static List<byte[]> divideArray(byte[] source, int chunksize) {
public void processCotEvent(CotEvent cotEvent, String[] strings) {
Log.d(TAG, cotEvent.toString());
DataPacket dp;

byte[] cotAsBytes = cotShrinker.toByteArrayLossy(cotEvent);

Log.d(TAG, "Size: " + cotAsBytes.length);

if (cotAsBytes.length < 236) {
Expand All @@ -122,32 +130,32 @@ public void processCotEvent(CotEvent cotEvent, String[] strings) {

List<byte[]> chunkList = divideArray(cotAsBytes, 200);


int chunks = (int) Math.floor(cotAsBytes.length / 200);
chunks++;

Log.d(TAG, "Sending " + chunks);

byte[] chunk_hdr = String.format(Locale.US,"CHUNK_%d_", cotAsBytes.length).getBytes();
Log.d(TAG, "Chunk head size: " + chunk_hdr.length);

for (byte[] c : chunkList) {
Log.d(TAG, "Size: " + c.length);
Log.d(TAG, new String(c));

byte[] combined = new byte[chunk_hdr.length + c.length];
System.arraycopy(chunk_hdr, 0, combined, 0, chunk_hdr.length);
System.arraycopy(c, 0, combined, chunk_hdr.length, c.length);

Log.d(TAG, "Combined length: " + combined.length);
Log.d(TAG, new String(combined));
// send out 1 chunk
dp = new DataPacket("^all", combined, ATAK_FORWARDER, DataPacket.ID_LOCAL, System.currentTimeMillis(), 0, MessageStatus.UNKNOWN, 3, 0);
try {
mMeshService.send(dp);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
Log.d(TAG, "====");
}

// We're done chunking
dp = new DataPacket("^all", new byte[] {'E', 'N', 'D'}, ATAK_FORWARDER, DataPacket.ID_LOCAL, System.currentTimeMillis(), 0, MessageStatus.UNKNOWN, 3, 0);
try {
mMeshService.send(dp);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
}

Expand Down Expand Up @@ -196,6 +204,14 @@ public void onServiceDisconnected(ComponentName className) {
view.getContext().bindService(mServiceIntent, mServiceConnection, Context.BIND_AUTO_CREATE);

mw = new MeshtasticWidget(context, view);

// Grab all the logcat output for ATAK to help debug
try {
String filePath = Environment.getExternalStorageDirectory() + "/atak/logcat.txt";
Runtime.getRuntime().exec(new String[]{"logcat", "-f", filePath});
} catch (IOException e) {
throw new RuntimeException(e);
}
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,30 @@
import android.content.Intent;

import com.atakmap.android.cot.CotMapComponent;
import com.atakmap.android.cot.CotMarkerRefresher;
import com.atakmap.android.importexport.CotEventFactory;
import com.atakmap.android.maps.MapItem;
import com.atakmap.android.maps.MapView;
import com.atakmap.android.user.PlacePointTool;
import com.atakmap.comms.CommsMapComponent;
import com.atakmap.coremap.cot.event.CotDetail;
import com.atakmap.coremap.cot.event.CotEvent;
import com.atakmap.coremap.log.Log;
import com.atakmap.coremap.maps.time.CoordinatedTime;
import com.geeksville.mesh.DataPacket;
import com.geeksville.mesh.MessageStatus;
import com.geeksville.mesh.NodeInfo;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.zip.GZIPInputStream;

public class MeshtasticReceiver extends BroadcastReceiver {

Expand Down Expand Up @@ -65,60 +78,68 @@ else if (action.equals(MeshtasticMapComponent.ACTION_NODE_CHANGE)) {
int cotSize = 0;
protected void receive(Intent intent) {
DataPacket payload = intent.getParcelableExtra(MeshtasticMapComponent.EXTRA_PAYLOAD);

int dataType = payload.getDataType();

Log.v(TAG, "handleReceive(), dataType: " + dataType);

if (dataType == 257) {
String message = new String(payload.getBytes());
if (message.startsWith("CHUNK")) {
Log.d(TAG, "Received Chunked message");
chunking = true;
if (cotSize == 0) {
cotSize = Integer.parseInt(message.split("_")[1]);
Log.d(TAG, "CoT size: " + cotSize);
Log.d(TAG, "Chunk CoT size: " + cotSize);
}

int chunk_hdr_size = String.format(Locale.US, "CHUNKS_%d_", cotSize).getBytes().length - 1;
int chunk_hdr_size = String.format(Locale.US, "CHUNK_%d_", cotSize).getBytes().length;
byte[] chunk = new byte[payload.getBytes().length - chunk_hdr_size];
Log.d(TAG, "Chunk header size: " + chunk_hdr_size);
System.arraycopy(payload.getBytes(), chunk_hdr_size, chunk, 0, payload.getBytes().length - chunk_hdr_size);

Log.d(TAG, "Chunk: " + new String(chunk));
chunks.add(chunk);

} else if (chunking) {
} else if (message.startsWith("END") && chunking) {
Log.d(TAG, "Chunking");
byte[] combined = new byte[cotSize];

int i = 0;
for (byte[] b: chunks) {
Log.d(TAG, new String(b));
Log.d(TAG, "len: " + b.length);
Log.d(TAG, "====");
System.arraycopy(b,0, combined, i, b.length);
i += b.length;
Log.d(TAG, "i: " + i);
}

Log.d(TAG, "Chunked size: " + i);
cotSize = 0;
chunking = false;
chunks.clear();

try {
CotEvent cotEvent = MeshtasticMapComponent.cotShrinker.toCotEvent(combined);
if (cotEvent != null && cotEvent.isValid()) {
Log.d(TAG, "Chunked CoT Received");

CotEvent cotEvent = MeshtasticMapComponent.cotShrinker.toCotEvent(combined);
if (cotEvent != null && cotEvent.isValid()) {
Log.d(TAG, "CoT Received");
CotMapComponent.getInternalDispatcher().dispatch(cotEvent);
} else {
Log.d(TAG, "Failed to libcotshrink: " + new String(combined));
cotEvent.setStale(new CoordinatedTime().addDays(3));
CotMapComponent.getInternalDispatcher().dispatch(cotEvent);

MapItem mi = MapView.getMapView().getMapItem(cotEvent.getUID());
mi.persist(MapView.getMapView().getMapEventDispatcher(), null, this.getClass());


} else {
Log.d(TAG, "Failed to libcotshrink: " + new String(combined));
}
} catch(Throwable e) {
e.printStackTrace();
}
chunking = false;
chunks.clear();

}
else {
CotEvent cotEvent = MeshtasticMapComponent.cotShrinker.toCotEvent(payload.getBytes());
if (cotEvent.isValid()) {
Log.d(TAG, "CoT Received");
CotMapComponent.getInternalDispatcher().dispatch(cotEvent);
try {
CotEvent cotEvent = MeshtasticMapComponent.cotShrinker.toCotEvent(payload.getBytes());
if (cotEvent.isValid()) {
Log.d(TAG, "CoT Received");
CotMapComponent.getInternalDispatcher().dispatch(cotEvent);
}
} catch (Throwable e) {
e.printStackTrace();
}

}
}
}
Expand Down

0 comments on commit d54db55

Please sign in to comment.