Skip to content

Commit

Permalink
/api/binmsgs
Browse files Browse the repository at this point in the history
  • Loading branch information
jvde-github committed Feb 27, 2025
1 parent ae30c07 commit cd4c94f
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 13 deletions.
5 changes: 5 additions & 0 deletions Application/WebViewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,11 @@ void WebViewer::Request(TCP::ServerConnection &c, const std::string &response, b
s->SendEvent("log", m.toJSON());
}
}
else if (r == "/api/binmsgs")
{
std::string content = ships.getBinaryMessagesJSON();
Response(c, "application/json", content, use_zlib & gzip);
}
else if (r == "/custom/plugins.js")
{
Response(c, "application/javascript", params + plugins + plugin_code + "}\nserver_version = false;\naboutMDpresent = " + (aboutPresent ? "true" : "false") + ";\ncommunityFeed = " + (commm_feed ? "true" : "false") + ";\n", use_zlib & gzip);
Expand Down
78 changes: 78 additions & 0 deletions Tracking/DB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,81 @@ bool DB::updateShip(const JSON::JSON &data, TAG &tag, Ship &ship)
return positionUpdated;
}

void DB::processBinaryMessage(const JSON::JSON &data, Ship &ship)
{
const AIS::Message *msg = (AIS::Message *)data.binary;
int type = msg->type();

// Only process binary message types 6 and 8
if (type != 6 && type != 8)
return;

int dac = -1;
int fi = -1;
bool hasPosition = false;

// Extract DAC and FI from message
for (const auto &p : data.getProperties()) {
if (p.Key() == AIS::KEY_DAC)
dac = p.Get().getInt();
else if (p.Key() == AIS::KEY_FID)
fi = p.Get().getInt();
else if (p.Key() == AIS::KEY_LAT || p.Key() == AIS::KEY_LON)
hasPosition = true;
}

if (dac != -1 && fi != -1) {
std::string jsonStr;
builder.stringify(data, jsonStr);

addBinaryMessage(jsonStr, type, dac, fi, hasPosition);
}
}

void DB::addBinaryMessage(const std::string& jsonStr, int msgType, int dac, int fi, bool hasPos) {
BinaryMessage& msg = binaryMessages[binaryMsgIndex];

msg.json = jsonStr;
msg.type = msgType;
msg.dac = dac;
msg.fi = fi;
msg.hasPosition = hasPos;
msg.timestamp = time(nullptr);
msg.used = true;

binaryMsgIndex = (binaryMsgIndex + 1) % MAX_BINARY_MESSAGES;
}

std::string DB::getBinaryMessagesJSON() const {
std::string result = "[";
bool first = true;

// Start from newest message and go backward
int startIndex = (binaryMsgIndex + MAX_BINARY_MESSAGES - 1) % MAX_BINARY_MESSAGES;

for (int i = 0; i < MAX_BINARY_MESSAGES; i++) {
int idx = (startIndex - i + MAX_BINARY_MESSAGES) % MAX_BINARY_MESSAGES;
const BinaryMessage& msg = binaryMessages[idx];

if (!msg.used) continue;

if (!first) result += ",";
first = false;

result += "{";
result += "\"type\":" + std::to_string(msg.type) + ",";
result += "\"dac\":" + std::to_string(msg.dac) + ",";
result += "\"fi\":" + std::to_string(msg.fi) + ",";
result += "\"hasPosition\":" + std::string(msg.hasPosition ? "true" : "false") + ",";
result += "\"timestamp\":" + std::to_string(msg.timestamp) + ",";
result += "\"message\":" + msg.json;
result += "}";
}

result += "]";
return result;
}

void DB::Receive(const JSON::JSON *data, int len, TAG &tag)
{

Expand Down Expand Up @@ -811,6 +886,9 @@ void DB::Receive(const JSON::JSON *data, int len, TAG &tag)
tag.shipclass = ship.shipclass;
tag.speed = ship.speed;

if(type == 6 || type ==8 )
processBinaryMessage(data[0], ship);

if (position_updated && isValidCoord(lat_old, lon_old))
{
// flat earth approximation, roughly 10 nmi
Expand Down
52 changes: 39 additions & 13 deletions Tracking/DB.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,29 @@
#include "JSON/StringBuilder.h"
#include "Ships.h"


struct PathPoint {
struct PathPoint
{
float lat, lon;
uint32_t mmsi = 0;
int count = 0;
int next = 0;
};

class DB : public StreamIn<JSON::JSON>, public StreamIn<AIS::GPS>, public StreamOut<JSON::JSON> {
struct BinaryMessage
{
std::string json;
int type;
int dac;
int fi;
bool hasPosition;
time_t timestamp;
bool used;

BinaryMessage() : used(false) {}
};

class DB : public StreamIn<JSON::JSON>, public StreamIn<AIS::GPS>, public StreamOut<JSON::JSON>
{

JSON::StringBuilder builder;

Expand Down Expand Up @@ -64,19 +78,26 @@ class DB : public StreamIn<JSON::JSON>, public StreamIn<AIS::GPS>, public Stream
int findShip(uint32_t mmsi);
int createShip();
void moveShipToFront(int);
bool updateFields(const JSON::Property& p, const AIS::Message* msg, Ship& v, bool allowApproximate);
bool updateFields(const JSON::Property &p, const AIS::Message *msg, Ship &v, bool allowApproximate);

bool updateShip(const JSON::JSON&, TAG&, Ship&);
bool updateShip(const JSON::JSON &, TAG &, Ship &);
void addToPath(int ptr);

static void getDistanceAndBearing(float lat1, float lon1, float lat2, float lon2, float& distance, int& bearing);
static void getDistanceAndBearing(float lat1, float lon1, float lat2, float lon2, float &distance, int &bearing);

void getShipJSON(const Ship& ship, std::string& content, long int now);
void getShipJSON(const Ship &ship, std::string &content, long int now);
std::string getSinglePathJSON(int);
bool isNextPathPoint(int idx, uint32_t mmsi, int count) { return idx != -1 && paths[idx].mmsi == mmsi && paths[idx].count < count; }

AIS::Filter filter;

static const int MAX_BINARY_MESSAGES = 10;
BinaryMessage binaryMessages[MAX_BINARY_MESSAGES];
int binaryMsgIndex = 0;

void addBinaryMessage(const std::string& jsonStr, int msgType, int dac, int fi, bool hasPos);
void processBinaryMessage(const JSON::JSON &data, Ship &ship);

public:
DB() : builder(&AIS::KeyMap, JSON_DICT_FULL) {}

Expand All @@ -86,9 +107,10 @@ class DB : public StreamIn<JSON::JSON>, public StreamIn<AIS::GPS>, public Stream
void setTimeHistory(int t) { TIME_HISTORY = t; }
void setShareLatLon(bool b) { latlon_share = b; }
bool getShareLatLon() { return latlon_share; }

bool setUseGPS(bool b) { return use_GPS = b; }
void setLatLon(float lat, float lon) {
void setLatLon(float lat, float lon)
{
this->lat = lat;
this->lon = lon;
}
Expand All @@ -100,15 +122,17 @@ class DB : public StreamIn<JSON::JSON>, public StreamIn<AIS::GPS>, public Stream

void setOwnMMSI(uint32_t mmsi) { own_mmsi = mmsi; }

void Receive(const JSON::JSON* data, int len, TAG& tag);
void Receive(const AIS::GPS* data, int len, TAG& tag) {
if (use_GPS) {
void Receive(const JSON::JSON *data, int len, TAG &tag);
void Receive(const AIS::GPS *data, int len, TAG &tag)
{
if (use_GPS)
{
lat = data[0].getLat();
lon = data[0].getLon();
}
}

void getBinary(std::vector<char>&);
void getBinary(std::vector<char> &);
std::string getShipJSON(int mmsi);
std::string getJSON(bool full = false);
std::string getJSONcompact(bool full = false);
Expand All @@ -124,4 +148,6 @@ class DB : public StreamIn<JSON::JSON>, public StreamIn<AIS::GPS>, public Stream
void setServerMode(bool b) { server_mode = b; }
void setMsgSave(bool b) { msg_save = b; }
void setFilterOption(std::string &opt, std::string &arg) { filter.SetOption(opt, arg); }

std::string getBinaryMessagesJSON() const;
};

0 comments on commit cd4c94f

Please sign in to comment.