Skip to content

Commit 769867a

Browse files
committed
bug fixes and test fixes
1 parent 35d2572 commit 769867a

File tree

5 files changed

+269
-160
lines changed

5 files changed

+269
-160
lines changed

tak/cot.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,12 @@ const makeTAKNode = (RED) => {
3838
let value = RED.util.getMessageProperty(msg, node.property);
3939
let payload = handlePayload(value);
4040

41-
if (payload === undefined || payload === null) {
41+
if (typeof payload === "undefined" || payload === null) {
4242
node.error({ message: "Undefined or null payload." });
4343
return;
4444
}
4545

4646
let error = payload.error;
47-
4847
if (typeof error !== "undefined" && error !== null) {
4948
node.error(error);
5049
} else {

tak/cotLib.js

+168-111
Original file line numberDiff line numberDiff line change
@@ -193,19 +193,20 @@ const XML_DECLARATION = {
193193
* @param {object} payload - Payload to encode.
194194
*/
195195
const encodeCOT = (payload) => {
196-
console.log("encodeCOT payload:")
197-
console.log(payload)
198196
delete payload.error;
199197

198+
if (typeof payload !== 'object' || Object.keys(payload).length === 0) {
199+
return [{ payload: "" }, { payload: Buffer.from([]) }, { payload: Buffer.from([]) }];
200+
}
201+
202+
203+
200204
let takproto;
201205
let xmlPayload;
202206
let protojson;
203207

204208
if (typeof payload.cotEvent !== "undefined" && payload.cotEvent !== null) {
205-
206209
protojson = payload;
207-
// console.log("PROTOJSON")
208-
// console.log(protojson)
209210

210211
// FIXME: We lose xmlDetail here:
211212
let cotJS = proto.protojs2cotjs(protojson);
@@ -231,8 +232,6 @@ const encodeCOT = (payload) => {
231232
}
232233

233234
payload = cotJS;
234-
// console.log("PAYLOAD")
235-
// console.log(payload)
236235
}
237236

238237
if (!payload._declaration) {
@@ -241,16 +240,10 @@ const encodeCOT = (payload) => {
241240

242241
// Plain XML
243242
xmlPayload = cot.js2xml(payload);
244-
// console.log("xmlPayload:")
245-
// console.log(xmlPayload)
246243

247244
const jsonPayload = cot.xml2js(xmlPayload);
248-
console.log("jsonPayload")
249-
console.log(jsonPayload)
250245

251246
const protojs = cotjs2protojs(jsonPayload);
252-
console.log("protojs")
253-
console.log(protojs)
254247

255248
takproto = proto.js2proto(protojs);
256249

@@ -300,6 +293,7 @@ const convertXML = (payload) => {
300293
message: "Attempted to decode payload as XML.",
301294
exception: err,
302295
};
296+
303297
}
304298

305299
if (typeof cotjson === "undefined" || cotjson === null) {
@@ -315,16 +309,20 @@ const convertXML = (payload) => {
315309
cotjson.event.point === null
316310
) {
317311
cotjson.error = { message: "No Point Element returned from XML decoder." };
318-
return cotjson
319312
}
320313

314+
return cotjson
321315
};
322316

323317
const cotjs2protojs = (cotjs) => {
324318
if (typeof cotjs.event === "undefined" || cotjs.event === null) {
325319
return;
326320
}
327321

322+
if (typeof cotjs.event.point === "undefined" || cotjs.event.point === null) {
323+
return;
324+
}
325+
328326
const protojs = {
329327
takControl: {},
330328
cotEvent: {
@@ -398,146 +396,205 @@ const handlePayload = (payload) => {
398396
error: undefined,
399397
};
400398

401-
let plType = typeof payload;
402-
403-
if (typeof cot === "undefined" || cot === null) {
399+
if (typeof payload === "undefined" || payload === null) {
404400
combo.error = { message: "Attempted to parse empty payload." };
405401
return combo;
406402
}
407403

408-
/*
409-
CoT-JSON?
410-
Protobuf Buffer?
411-
*/
412-
if (plType === "object") {
413-
// Probably Protobuf
414-
if (Buffer.isBuffer(payload) && payload[0] === TAK_MAGICBYTE) {
404+
let plType = typeof payload;
405+
switch (plType) {
406+
case "object":
407+
combo = processObjectPayload(payload);
408+
break;
409+
case "string":
410+
combo = processStringPayload(payload);
411+
break;
412+
default:
413+
combo.error = { message: `Unsupported payload type: ${plType}` };
414+
break;
415+
}
415416

416-
let protojson = decodeCOT(payload);
417-
combo.payload = [{ payload: protojson }];
417+
return combo;
418+
};
418419

419-
let takproto;
420-
try {
421-
takproto = proto.js2proto(protojson);
422-
} catch (err) {
423-
combo.error = {
424-
message: "Error converting Proto JSON to Proto Buffer.",
425-
exception: err,
426-
};
427-
return combo;
428-
}
429420

430-
let takbuffers;
431-
try {
432-
takbuffers = takproto2buffers(takproto);
433-
} catch (err) {
434-
combo.error = {
435-
message: "Error converting takproto to buffers.",
436-
exception: err,
437-
};
438-
return combo;
439-
}
421+
// Maybe it's raw XML CoT
422+
const processStringPayload = (payload) => {
423+
let combo = {
424+
// XML MESH STREAM
425+
payload: [undefined, undefined, undefined],
426+
error: undefined,
427+
};
440428

441-
combo.payload.push(...takbuffers);
442-
} else if (Buffer.isBuffer(payload)) {
443-
plType = "string";
444-
payload = payload.toString();
445-
} else {
446-
try {
447-
combo.payload = encodeCOT(payload);
448-
} catch (err) {
449-
combo.error = {
450-
message: "Could not encode TAK payload.",
451-
exception: err,
452-
payload: payload,
453-
};
454-
throw err;
455-
// return combo;
456-
}
457-
}
429+
let cotjson
430+
// Maybe it's raw XML CoT
431+
try {
432+
cotjson = convertXML(payload);
433+
} catch (err) {
434+
combo.error = {
435+
message: "Error convering XML string to JSON: " + err,
436+
exception: err,
437+
};
438+
return combo;
439+
}
440+
441+
if (typeof cotjson === "undefined" || cotjson === null) {
442+
combo.error = {message: "cotjson undefined"};
443+
return combo;
458444
}
459445

460-
// Maybe it's raw XML CoT
461-
if (plType === "string") {
446+
combo.payload = [{ payload: cotjson }];
447+
if (typeof cotjson.event === "undefined" && cotjson.event === null) {
448+
combo.error = {
449+
message: "No Event Element returned from XML decoder.",
450+
};
451+
return combo;
452+
}
462453

463-
let cotjson = convertXML(payload);
454+
if (
455+
typeof cotjson.event.point === "undefined" &&
456+
cotjson.event.point === null
457+
) {
458+
combo.error = {
459+
message: "No Point Element returned from XML decoder.",
460+
};
461+
return combo;
462+
}
464463

465-
if (typeof cotjson === "undefined" || cotjson === null) {
466-
combo.error = "cotjson undefined"
467-
return combo
468-
}
464+
let protojson = convertCoTJSON(cotjson);
465+
if (protojson.error) {
466+
combo.error = {message: protojson.error};
467+
return combo;
468+
}
469469

470-
combo.payload = [{ payload: cotjson }];
471-
if (typeof cotjson.event === "undefined" && cotjson.event === null) {
472-
return combo;
473-
}
470+
/* Shove remaining <detail> sub-Elements into xmlDetail.
471+
See: https://github.com/deptofdefense/AndroidTacticalAssaultKit-CIV/blob/master/commoncommo/core/impl/protobuf/detail.proto
472+
*/
473+
let options = {
474+
attrkey: "_attributes",
475+
charkey: "_",
476+
explicitRoot: 0,
477+
renderOpts: { pretty: false },
478+
headless: true,
479+
rootName: MAGIC_ROOT,
480+
};
474481

475-
if (
476-
typeof cotjson.event.point === "undefined" &&
477-
cotjson.event.point === null
478-
) {
482+
const detail = cotjson.event.detail;
483+
if (typeof detail !== "undefined" && detail !== null) {
484+
let xmlDetail;
485+
try {
486+
xmlDetail = new xml2js.Builder(options).buildObject(detail);
487+
protojson.cotEvent.xmlDetail = xmlDetail
488+
.replace(`<${options.rootName}>`, "")
489+
.replace(`</${options.rootName}>`, "");
490+
} catch (err) {
491+
combo.error = {
492+
message: "Attempted to convert Detail Element.",
493+
exception: err,
494+
};
479495
return combo;
480496
}
497+
}
481498

482-
let protojson = convertCoTJSON(cotjson);
483-
if (protojson.error) {
484-
combo.error = protojson.error;
485-
return combo;
486-
}
499+
let takproto;
500+
try {
501+
takproto = proto.js2proto(protojson);
502+
} catch (err) {
503+
combo.error = {
504+
message: "Error converting Protobuf JSON to Protobuf Buffer.",
505+
exception: err,
506+
};
507+
return combo;
508+
}
487509

488-
/* Shove remaining <detail> sub-Elements into xmlDetail.
489-
See: https://github.com/deptofdefense/AndroidTacticalAssaultKit-CIV/blob/master/commoncommo/core/impl/protobuf/detail.proto
490-
*/
491-
let options = {
492-
attrkey: "_attributes",
493-
charkey: "_",
494-
explicitRoot: 0,
495-
renderOpts: { pretty: false },
496-
headless: true,
497-
rootName: MAGIC_ROOT,
510+
let takbuffers;
511+
try {
512+
takbuffers = takproto2buffers(takproto);
513+
} catch (err) {
514+
combo.error = {
515+
message: "Error converting takproto to buffers.",
516+
exception: err,
498517
};
518+
return combo;
519+
}
499520

500-
const detail = cotjson.event.detail;
501-
if (typeof detail !== "undefined" && detail !== null) {
502-
let xmlDetail;
503-
try {
504-
xmlDetail = new xml2js.Builder(options).buildObject(detail);
505-
protojson.cotEvent.xmlDetail = xmlDetail
506-
.replace(`<${options.rootName}>`, "")
507-
.replace(`</${options.rootName}>`, "");
508-
} catch (err) {
509-
combo.error = {
510-
message: "Attempted to convert Detail Element.",
511-
exception: err,
512-
};
513-
}
514-
}
521+
combo.payload.push(...takbuffers);
522+
523+
return combo;
524+
}
525+
526+
/*
527+
CoT-JSON?
528+
Protobuf Buffer?
529+
*/
530+
const processObjectPayload = (payload) => {
531+
let combo = {
532+
// XML MESH STREAM
533+
payload: [undefined, undefined, undefined],
534+
error: undefined,
535+
};
536+
537+
// Probably Protobuf
538+
if (Buffer.isBuffer(payload) && payload[0] === TAK_MAGICBYTE) {
539+
let protojson = decodeCOT(payload);
540+
combo.payload = [{ payload: protojson }];
515541

516542
let takproto;
517543
try {
518544
takproto = proto.js2proto(protojson);
519545
} catch (err) {
520546
combo.error = {
521-
message: "Error converting Protobuf JSON to Protobuf Buffer.",
547+
message: "Error converting JSON to Protobuf: " + err,
522548
exception: err,
523549
};
550+
return combo;
524551
}
525552

526553
let takbuffers;
527554
try {
528555
takbuffers = takproto2buffers(takproto);
529556
} catch (err) {
530557
combo.error = {
531-
message: "Error converting takproto to buffers.",
558+
message: "Error converting takproto to buffers: " + err,
532559
exception: err,
533560
};
534561
return combo;
535562
}
536563

537564
combo.payload.push(...takbuffers);
565+
} else if (Buffer.isBuffer(payload)) {
566+
try {
567+
payload = payload.toString();
568+
} catch (err) {
569+
combo.error = {
570+
message: "Could not convert Buffer to String: " + err,
571+
exception: err,
572+
};
573+
return combo;
574+
}
575+
try {
576+
combo = handlePayload(payload);
577+
} catch (err) {
578+
combo.error = {
579+
message: "Could not handle Buffer as String: " + err,
580+
exception: err,
581+
};
582+
return combo;
583+
}
584+
} else {
585+
try {
586+
combo.payload = encodeCOT(payload);
587+
} catch (err) {
588+
combo.error = {
589+
message: "Could not encode TAK payload: " + err,
590+
exception: err,
591+
payload: payload,
592+
};
593+
return combo;
594+
}
538595
}
539596

540597
return combo;
541598
};
542599

543-
module.exports = { handlePayload, cotType2SIDC };
600+
module.exports = { handlePayload, cotType2SIDC, encodeCOT, decodeCOT };

0 commit comments

Comments
 (0)