Engage Engine API  1.244.9084
Loading...
Searching...
No Matches
engage.cpp
1//
2// Copyright (c) 2019 Rally Tactical Systems, Inc.
3// All rights reserved.
4//
5
6#include <nan.h>
7#include <node_buffer.h>
8#include <string>
9#include <iostream>
10#include <thread>
11#include <map>
12#include <mutex>
13#include <atomic>
14
15#include "EngageInterface.h"
16#include "EngagePlatformNotifications.h"
17
18using namespace std;
19using namespace Nan;
20using namespace v8;
21
22// Makes a binding
23#define ENGAGE_BINDING(_nm) \
24 Nan::Set(target, \
25 New<String>(#_nm).ToLocalChecked(), \
26 GetFunction(New<FunctionTemplate>(_nm)).ToLocalChecked());
27
28// Gets inbound string parameter @ _infoIndex
29#define STRVAL(_infoIndex) \
30 *Nan::Utf8String(info[_infoIndex]->ToString(Nan::GetCurrentContext()).FromMaybe(v8::Local<v8::String>()))
31
32// Gets inbound integer parameter @ _infoIndex
33#define INTVAL(_index) \
34 info[_index]->Int32Value(Nan::GetCurrentContext()).FromJust()
35
36// Return an integer
37#define NANRETI(_expr) \
38 info.GetReturnValue().Set(_expr);
39
40// Return a string
41#define NANRETS(_expr) \
42 info.GetReturnValue().Set(New(_expr).ToLocalChecked());
43
44// Defines a callback with no parameters
45#define ENGAGE_CB_NO_PARAMS(_ename) \
46 void on_ ## _ename(const char *eventExtraJson) \
47 { \
48 CrossThreadCallbackWorker *cbw = getCallback(#_ename); \
49 if(!cbw) \
50 { \
51 return; \
52 } \
53 cbw->enqueue(eventExtraJson); \
54 cbw->RELEASE_OBJECT_REFERENCE(); \
55 }
56
57// Defines a callback with a string parameter
58#define ENGAGE_CB_STR_PARAM(_ename) \
59 void on_ ## _ename(const char *str, const char *eventExtraJson) \
60 { \
61 CrossThreadCallbackWorker *cbw = getCallback(#_ename); \
62 if(!cbw) \
63 { \
64 return; \
65 } \
66 cbw->enqueue(str, eventExtraJson); \
67 cbw->RELEASE_OBJECT_REFERENCE(); \
68 }
69
70// Defines a callback with an ID (a string parameter)
71#define ENGAGE_CB_ID_PARAM(_ename) \
72 void on_ ## _ename(const char *id, const char *eventExtraJson) \
73 { \
74 CrossThreadCallbackWorker *cbw = getCallback(#_ename); \
75 if(!cbw) \
76 { \
77 return; \
78 } \
79 cbw->enqueue(id, eventExtraJson); \
80 cbw->RELEASE_OBJECT_REFERENCE(); \
81 }
82
83// Defines a callback with an ID (a string parameter) plus 1 strnig
84#define ENGAGE_CB_ID_PLUS_ONE_STRING_PARAM(_ename) \
85 void on_ ## _ename(const char *id, const char *s, const char *eventExtraJson) \
86 { \
87 CrossThreadCallbackWorker *cbw = getCallback(#_ename); \
88 if(!cbw) \
89 { \
90 return; \
91 } \
92 cbw->enqueue(id, s, eventExtraJson); \
93 cbw->RELEASE_OBJECT_REFERENCE(); \
94 }
95
96// A callback table entry
97#define ENGAGE_CB_TABLE_ENTRY(_pfn, _ename) \
98 g_eventCallbacks._pfn = on_ ## _ename;
99
100// This little class wraps callbacks into JS from non-JS threads. It does so by
101// posting the callback/event onto the libuv event loop from which the instance
102// of this worker class was created. So ... be very careful only to create instances
103// of this class from a thread that originated in libuv!!
105{
106public:
108 {
109 public:
110 typedef enum {ptString, ptInt, ptStringVector} Type_t;
111
112 Type_t _type;
113 };
114
116 {
117 public:
118 StringParameter(const char *s)
119 {
120 _type = ptString;
121 if(s != nullptr && s[0] != 0)
122 {
123 _val = s;
124 }
125 }
126
127 std::string _val;
128 };
129
130 class IntParameter : public Parameter
131 {
132 public:
133 IntParameter(int i)
134 {
135 _type = ptInt;
136 _val = i;
137 }
138
139 int _val;
140 };
141
143 {
144 public:
145 StringVectorParameter(const char *array[])
146 {
147 _type = ptStringVector;
148
149 // Our array is either null to begin with or terminated with a nullptr at the end
150 if(array != nullptr)
151 {
152 size_t index = 0;
153 while(array[index] != nullptr)
154 {
155 _val.push_back(array[index] != nullptr ? array[index] : "");
156 index++;
157 }
158 }
159 }
160
161 std::vector<std::string> _val;
162 };
163
164 explicit CrossThreadCallbackWorker(v8::Local<v8::Function> fn)
165 {
166 Nan::HandleScope scope;
167
168 // We're going to post this work on this libuv queue
169 _evLoop = GetCurrentEventLoop();
170
171 // Marshal the V8 function into a NAN callback structure
172 _cb.Reset(fn);
173
174 _workCtx.data = this;
175 _isBusy = false;
176 _refCount = 0;
177
178 // TODO: I'm not convinced we even need this as there's no object here to get
179 // garbage-collected. TBD !!
180 v8::Local<v8::Object> obj = New<v8::Object>();
181 _persistentHandle.Reset(obj);
182 _resource = new AsyncResource("CrossThreadCallbackWorker", obj);
183
184 ADD_OBJECT_REFERENCE();
185 }
186
188 {
189 Nan::HandleScope scope;
190
191 if (!_persistentHandle.IsEmpty())
192 {
193 _persistentHandle.Reset();
194 }
195
196 delete _resource;
197 }
198
199 void ADD_OBJECT_REFERENCE()
200 {
201 assert(_refCount >= 0);
202 _refCount++;
203 }
204
205 void RELEASE_OBJECT_REFERENCE()
206 {
207 assert(_refCount > 0);
208 if(_refCount.fetch_sub(1) == 1)
209 {
210 delete this;
211 }
212 }
213
214 void enqueue(const char *extra)
215 {
216 std::vector<Parameter*> *params = new std::vector<Parameter*>();
217 params->push_back(new StringParameter(extra));
218 enqueue(params);
219 }
220
221 void enqueue(const char *s, const char *extra)
222 {
223 std::vector<Parameter*> *params = new std::vector<Parameter*>();
224 params->push_back(new StringParameter(s));
225 params->push_back(new StringParameter(extra));
226 enqueue(params);
227 }
228
229 void enqueue(const char *s1, const char *s2, const char *extra)
230 {
231 std::vector<Parameter*> *params = new std::vector<Parameter*>();
232 params->push_back(new StringParameter(s1));
233 params->push_back(new StringParameter(s2));
234 params->push_back(new StringParameter(extra));
235 enqueue(params);
236 }
237
238 void enqueue(std::vector<Parameter*> *parameters)
239 {
240 // We need to wait here for the worker to become available (it may already be
241 // queued in JS). The chances of this happening are very slim as callbacks
242 // don't happen that often and, when they do, they'll return in just a few
243 // microseconds. But, let's be paranoid shall we!
244 _lock.lock();
245
246 while(_isBusy)
247 {
248 _lock.unlock();
249 std::this_thread::sleep_for(std::chrono::milliseconds(1));
250 _lock.lock();
251 }
252
253 // Pass over the pending parameters
254 _pendingParameters = parameters;
255
256 _isBusy = true;
257
258 _lock.unlock();
259
260 ADD_OBJECT_REFERENCE();
261 uv_queue_work(_evLoop,
262 &_workCtx,
263 CrossThreadCallbackWorker::onExecuteWork,
264 reinterpret_cast<uv_after_work_cb>(CrossThreadCallbackWorker::onWorkCompleted));
265 }
266
267 static void onExecuteWork(uv_work_t* workCtx)
268 {
269 // libuv wants us to execute something. But we don't have any actual work to do. So
270 // we'll just return.
271 }
272
273 static void onWorkCompleted(uv_work_t* workCtx)
274 {
275 // We'll just bounce this though to the instance's method
276 static_cast<CrossThreadCallbackWorker*>(workCtx->data)->internal_onWorkCompleted();
277 }
278
279private:
280 NAN_DISALLOW_ASSIGN_COPY_MOVE(CrossThreadCallbackWorker)
281
282 void internal_onWorkCompleted()
283 {
284 _lock.lock();
285
286 // The real work here is to make the callback...
287 Nan::HandleScope scope;
288
289 v8::Isolate *isolate = v8::Isolate::GetCurrent();
290 v8::Local<Context> context = v8::Context::New(isolate);
291
292 // ... which we'll do here.
293 if(_pendingParameters == nullptr || _pendingParameters->size() == 0)
294 {
295 _cb.Call(0, nullptr, _resource);
296 }
297 else
298 {
299 // We can only call into V8 here to build up the parameters because only now are we
300 // on a thread that V8 owns.
301 v8::Local<v8::Value> *argv = new v8::Local<v8::Value>[_pendingParameters->size()];
302
303 int index = 0;
304 for(std::vector<Parameter*>::iterator itr = _pendingParameters->begin();
305 itr != _pendingParameters->end();
306 itr++)
307 {
308 if((*itr)->_type == Parameter::ptString)
309 {
310 argv[index] = Nan::New<v8::String>(((StringParameter*)(*itr))->_val).ToLocalChecked();
311 }
312 else if((*itr)->_type == Parameter::ptStringVector)
313 {
314 StringVectorParameter *svp = (StringVectorParameter*)(*itr);
315 v8::Local<v8::Array> jsArray = Nan::New<v8::Array>(svp->_val.size());
316
317 int speakerIndex = 0;
318 for(std::vector<std::string>::iterator itrSpeakers = svp->_val.begin();
319 itrSpeakers != svp->_val.end();
320 itrSpeakers++)
321 {
322 #ifndef WIN32
323 #pragma GCC diagnostic push
324 #pragma GCC diagnostic ignored "-Wunused-result"
325 #endif
326 {
327 jsArray->Set(context, speakerIndex, v8::String::NewFromUtf8(isolate, itrSpeakers->c_str(), NewStringType::kNormal).ToLocalChecked());
328 }
329 #ifndef WIN32
330 #pragma GCC diagnostic pop
331 #endif
332
333 speakerIndex++;
334 }
335
336 argv[index] = jsArray;
337 }
338 else if((*itr)->_type == Parameter::ptInt)
339 {
340 argv[index] = Nan::New<v8::Integer>(((IntParameter*)(*itr))->_val);
341 }
342
343 index++;
344 }
345
346 // Call into JS-land
347 _cb.Call(_pendingParameters->size(), argv, _resource);
348
349 // Get rid of any pending parameters
350 if(_pendingParameters != nullptr)
351 {
352 for(std::vector<Parameter*>::iterator itr = _pendingParameters->begin();
353 itr != _pendingParameters->end();
354 itr++)
355 {
356 delete *itr;
357 }
358
359 _pendingParameters->clear();
360 delete _pendingParameters;
361 _pendingParameters = nullptr;
362 }
363 }
364
365 // ... and only now can we say that this worker is no longer in use - i.e. its out
366 // out the libuv queue and won't cause a bus error in case it gets reused very
367 // quickly (that can happen if this code runs in onExecuteWork).
368 _isBusy = false;
369
370 _lock.unlock();
371
372 // Finally, let go of the reference we added when this was enqueue
373 RELEASE_OBJECT_REFERENCE();
374 }
375
376 std::mutex _lock;
377 uv_loop_t *_evLoop;
378 uv_work_t _workCtx;
379 bool _isBusy;
380 Nan::Callback _cb;
381 Nan::Persistent<v8::Object> _persistentHandle;
382 AsyncResource *_resource;
383 std::atomic<int> _refCount;
384 std::vector<Parameter*> *_pendingParameters;
385};
386
387typedef std::map<std::string, CrossThreadCallbackWorker*> CallbackMap_t;
388
389static EngageEvents_t g_eventCallbacks;
390static bool g_wantCallbacks = true;
391static CallbackMap_t g_cbMap;
392static std::mutex g_cbMapLock;
393static std::string g_loggingHookFn;
394
395//--------------------------------------------------------
396// Returns the callback associated with an event name (if any)
397static CrossThreadCallbackWorker *getCallback(const char *cbName)
398{
399 if(!g_wantCallbacks)
400 {
401 return nullptr;
402 }
403
404 CrossThreadCallbackWorker *rc = nullptr;
405
406 g_cbMapLock.lock();
407
408 CallbackMap_t::iterator itr = g_cbMap.find(cbName);
409 if(itr != g_cbMap.end())
410 {
411 rc = itr->second;
412 rc->ADD_OBJECT_REFERENCE();
413 }
414
415 g_cbMapLock.unlock();
416
417 return rc;
418}
419
420
421// The following convey events from Engage up to JS. They all follow the same
422// basic flow of finding a callback for the event name and, if one is found, calling
423// it. Generally callbacks have no parameters, or a single string parameter. But,
424// some of them are a little unique. So, for those that look the same, we'll use the
425// ENGAGE_CB_xx_PARAMS macros. For the others, we'll actually write all the code for each.
426ENGAGE_CB_NO_PARAMS(engineStarted)
427ENGAGE_CB_NO_PARAMS(engineStopped)
428ENGAGE_CB_NO_PARAMS(engineAudioDevicesRefreshed)
429
430ENGAGE_CB_ID_PARAM(rpPausingConnectionAttempt)
431ENGAGE_CB_ID_PARAM(rpConnecting)
432ENGAGE_CB_ID_PARAM(rpConnected)
433ENGAGE_CB_ID_PARAM(rpDisconnected)
434void on_rpRoundtripReport(const char *id, uint32_t rtMs, uint32_t rtQualityRating, const char * eventExtraJson)
435{
436 CrossThreadCallbackWorker *cbw = getCallback("rpRoundtripReport");
437 if(!cbw)
438 {
439 return;
440 }
441
442 std::vector<CrossThreadCallbackWorker::Parameter*> *params = new std::vector<CrossThreadCallbackWorker::Parameter*>();
443 params->push_back(new CrossThreadCallbackWorker::StringParameter(id));
444 params->push_back(new CrossThreadCallbackWorker::IntParameter((int)rtMs));
445 params->push_back(new CrossThreadCallbackWorker::IntParameter((int)rtQualityRating));
446 params->push_back(new CrossThreadCallbackWorker::StringParameter(eventExtraJson));
447 cbw->enqueue(params);
448
449 cbw->RELEASE_OBJECT_REFERENCE();
450}
451
452ENGAGE_CB_ID_PARAM(groupCreated)
453ENGAGE_CB_ID_PARAM(groupCreateFailed)
454ENGAGE_CB_ID_PARAM(groupDeleted)
455
456ENGAGE_CB_ID_PARAM(groupConnected)
457ENGAGE_CB_ID_PARAM(groupConnectFailed)
458ENGAGE_CB_ID_PARAM(groupDisconnected)
459
460ENGAGE_CB_ID_PARAM(groupJoined)
461ENGAGE_CB_ID_PARAM(groupJoinFailed)
462ENGAGE_CB_ID_PARAM(groupLeft)
463
464ENGAGE_CB_ID_PARAM(groupRxStarted)
465ENGAGE_CB_ID_PARAM(groupRxEnded)
466
467ENGAGE_CB_ID_PARAM(groupRxMuted)
468ENGAGE_CB_ID_PARAM(groupRxUnmuted)
469ENGAGE_CB_ID_PLUS_ONE_STRING_PARAM(groupRxSpeakersChanged)
470
471ENGAGE_CB_ID_PLUS_ONE_STRING_PARAM(groupNodeDiscovered)
472ENGAGE_CB_ID_PLUS_ONE_STRING_PARAM(groupNodeRediscovered)
473ENGAGE_CB_ID_PLUS_ONE_STRING_PARAM(groupNodeUndiscovered)
474
475ENGAGE_CB_ID_PARAM(groupTxStarted);
476ENGAGE_CB_ID_PARAM(groupTxEnded);
477ENGAGE_CB_ID_PARAM(groupTxFailed);
478ENGAGE_CB_ID_PARAM(groupTxUsurpedByPriority);
479ENGAGE_CB_ID_PARAM(groupMaxTxTimeExceeded);
480
481ENGAGE_CB_ID_PARAM(groupTxMuted)
482ENGAGE_CB_ID_PARAM(groupTxUnmuted)
483
484ENGAGE_CB_ID_PLUS_ONE_STRING_PARAM(groupAssetDiscovered);
485ENGAGE_CB_ID_PLUS_ONE_STRING_PARAM(groupAssetRediscovered);
486ENGAGE_CB_ID_PLUS_ONE_STRING_PARAM(groupAssetUndiscovered);
487
488ENGAGE_CB_NO_PARAMS(licenseChanged)
489ENGAGE_CB_NO_PARAMS(licenseExpired)
490ENGAGE_CB_STR_PARAM(licenseExpiring)
491
492ENGAGE_CB_ID_PLUS_ONE_STRING_PARAM(groupTimelineEventStarted);
493ENGAGE_CB_ID_PLUS_ONE_STRING_PARAM(groupTimelineEventUpdated);
494ENGAGE_CB_ID_PLUS_ONE_STRING_PARAM(groupTimelineEventEnded);
495ENGAGE_CB_ID_PLUS_ONE_STRING_PARAM(groupTimelineReport);
496ENGAGE_CB_ID_PARAM(groupTimelineReportFailed);
497ENGAGE_CB_ID_PLUS_ONE_STRING_PARAM(groupTimelineGroomed);
498
499ENGAGE_CB_ID_PLUS_ONE_STRING_PARAM(groupHealthReport);
500ENGAGE_CB_ID_PARAM(groupHealthReportFailed);
501
502ENGAGE_CB_ID_PLUS_ONE_STRING_PARAM(groupStatsReport);
503ENGAGE_CB_ID_PARAM(groupStatsReportFailed);
504
505void on_groupRxVolumeChanged(const char *id, int16_t leftLevelPerc, int16_t rightLevelPerc, const char * eventExtraJson)
506{
507 CrossThreadCallbackWorker *cbw = getCallback("groupRxVolumeChanged");
508 if(!cbw)
509 {
510 return;
511 }
512
513 std::vector<CrossThreadCallbackWorker::Parameter*> *params = new std::vector<CrossThreadCallbackWorker::Parameter*>();
514 params->push_back(new CrossThreadCallbackWorker::StringParameter(id));
515 params->push_back(new CrossThreadCallbackWorker::IntParameter((int)leftLevelPerc));
516 params->push_back(new CrossThreadCallbackWorker::IntParameter((int)rightLevelPerc));
517 params->push_back(new CrossThreadCallbackWorker::StringParameter(eventExtraJson));
518 cbw->enqueue(params);
519
520 cbw->RELEASE_OBJECT_REFERENCE();
521}
522
523ENGAGE_CB_ID_PLUS_ONE_STRING_PARAM(groupRxDtmf)
524
525
526//--------------------------------------------------------
527// Registers an event name and the JS callback function
528NAN_METHOD(on)
529{
530 bool haveAFunction = false;
531 std::string functionName = STRVAL(0);
532
533 if(info.Length() >= 2 && (!info[1]->IsUndefined()) && (!info[1]->IsNull()))
534 {
535 haveAFunction = true;
536 }
537
538 g_cbMapLock.lock();
539
540 // Find our map entry
541 CallbackMap_t::iterator itr = g_cbMap.find(functionName.c_str());
542
543 // We don't yet have an entry in the map
544 if(itr == g_cbMap.end())
545 {
546 // If we don't have a function, then we're done
547 if(!haveAFunction)
548 {
549 g_cbMapLock.unlock();
550 return;
551 }
552
553 // We have a function but not yet an entry, make it and plug it into the map
554 g_cbMap[functionName.c_str()] = new CrossThreadCallbackWorker(Nan::To<v8::Function>(info[1]).ToLocalChecked());
555 }
556 else
557 {
558 // We have an entry ...
559
560 // ... get rid of it (we're either removing or replacing)
561 itr->second->RELEASE_OBJECT_REFERENCE();
562 g_cbMap.erase(itr);
563
564 // ... and maybe put in the new one
565 if(haveAFunction)
566 {
567 g_cbMap[functionName.c_str()] = new CrossThreadCallbackWorker(Nan::To<v8::Function>(info[1]).ToLocalChecked());
568 }
569 }
570
571 g_cbMapLock.unlock();
572}
573
574
575//--------------------------------------------------------
576NAN_METHOD(initialize)
577{
578 /*
579 #if defined(WIN32)
580 engageWin32LibraryInit();
581 #endif
582 */
583
584 memset(&g_eventCallbacks, 0, sizeof(g_eventCallbacks));
585
586 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_ENGINE_STARTED, engineStarted);
587 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_ENGINE_STOPPED, engineStopped);
588 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_ENGINE_AUDIO_DEVICES_REFRESHED, engineAudioDevicesRefreshed);
589
590 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_RP_PAUSING_CONNECTION_ATTEMPT, rpPausingConnectionAttempt);
591 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_RP_CONNECTING, rpConnecting);
592 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_RP_CONNECTED, rpConnected);
593 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_RP_DISCONNECTED, rpDisconnected);
594 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_RP_ROUNDTRIP_REPORT, rpRoundtripReport);
595
596 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_CREATED, groupCreated);
597 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_CREATE_FAILED, groupCreateFailed);
598 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_DELETED, groupDeleted);
599
600 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_CONNECTED, groupConnected);
601 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_CONNECT_FAILED, groupConnectFailed);
602 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_DISCONNECTED, groupDisconnected);
603
604 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_JOINED, groupJoined);
605 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_JOIN_FAILED, groupJoinFailed);
606 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_LEFT, groupLeft);
607 //ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_MEMBER_COUNT_CHANGED)(const char *pId, size_t newCount);
608
609 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_NODE_DISCOVERED, groupNodeDiscovered);
610 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_NODE_REDISCOVERED, groupNodeRediscovered);
611 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_NODE_UNDISCOVERED, groupNodeUndiscovered);
612
613 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_RX_STARTED, groupRxStarted);
614 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_RX_ENDED, groupRxEnded);
615 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_RX_SPEAKERS_CHANGED, groupRxSpeakersChanged);
616 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_RX_MUTED, groupRxMuted);
617 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_RX_UNMUTED, groupRxUnmuted);
618
619 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_TX_STARTED, groupTxStarted);
620 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_TX_ENDED, groupTxEnded);
621 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_TX_FAILED, groupTxFailed);
622 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_TX_USURPED_BY_PRIORITY, groupTxUsurpedByPriority);
623 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_MAX_TX_TIME_EXCEEDED, groupMaxTxTimeExceeded);
624 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_TX_MUTED, groupTxMuted);
625 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_TX_UNMUTED, groupTxUnmuted);
626
627 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_ASSET_DISCOVERED, groupAssetDiscovered);
628 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_ASSET_REDISCOVERED, groupAssetRediscovered);
629 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_ASSET_UNDISCOVERED, groupAssetUndiscovered);
630
631 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_LICENSE_CHANGED, licenseChanged);
632 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_LICENSE_EXPIRED, licenseExpired);
633 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_LICENSE_EXPIRING, licenseExpiring);
634
635 // TODO PFN_ENGAGE_GROUP_BLOB_SENT
636 // TODO PFN_ENGAGE_GROUP_BLOB_SEND_FAILED
637 // TODO PFN_ENGAGE_GROUP_BLOB_RECEIVED
638
639 // TODO PFN_ENGAGE_GROUP_RTP_SENT
640 // TODO PFN_ENGAGE_GROUP_RTP_SEND_FAILED
641 // TODO PFN_ENGAGE_GROUP_RTP_RECEIVED
642
643 // TODO PFN_ENGAGE_GROUP_RAW_SENT
644 // TODO PFN_ENGAGE_GROUP_RAW_SEND_FAILED
645 // TODO PFN_ENGAGE_GROUP_RAW_RECEIVED
646
647 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_TIMELINE_EVENT_STARTED, groupTimelineEventStarted);
648 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_TIMELINE_EVENT_UPDATED, groupTimelineEventUpdated);
649 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_TIMELINE_EVENT_ENDED, groupTimelineEventEnded);
650
651 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_TIMELINE_REPORT, groupTimelineReport);
652 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_TIMELINE_REPORT_FAILED, groupTimelineReportFailed);
653 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_TIMELINE_GROOMED, groupTimelineGroomed);
654
655 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_HEALTH_REPORT, groupHealthReport);
656 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_HEALTH_REPORT_FAILED, groupHealthReportFailed);
657
658 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_STATS_REPORT, groupStatsReport);
659 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_STATS_REPORT_FAILED, groupStatsReportFailed);
660
661 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_RX_VOLUME_CHANGED, groupRxVolumeChanged);
662 ENGAGE_CB_TABLE_ENTRY(PFN_ENGAGE_GROUP_RX_DTMF, groupRxDtmf);
663
664 engageRegisterEventCallbacks(&g_eventCallbacks);
665
666 NANRETI(engageInitialize(STRVAL(0), STRVAL(1), STRVAL(2)));
667}
668
669//--------------------------------------------------------
670NAN_METHOD(enableCallbacks)
671{
672 g_wantCallbacks = true;
673 NANRETI((int)ENGAGE_RESULT_OK);
674}
675
676//--------------------------------------------------------
677NAN_METHOD(disableCallbacks)
678{
679 g_wantCallbacks = false;
680 NANRETI((int)ENGAGE_RESULT_OK);
681}
682
683//--------------------------------------------------------
684NAN_METHOD(setLogLevel)
685{
686 NANRETI(engageSetLogLevel(INTVAL(0)));
687}
688
689//--------------------------------------------------------
690NAN_METHOD(setLogTagExtension)
691{
692 NANRETI(engageSetLogTagExtension(STRVAL(0)));
693}
694
695//--------------------------------------------------------
696NAN_METHOD(engageEnableSyslog)
697{
699}
700
701//--------------------------------------------------------
702NAN_METHOD(engageEnableWatchdog)
703{
705}
706
707//--------------------------------------------------------
708NAN_METHOD(shutdown)
709{
710 NANRETI(engageShutdown());
711
712 /*
713 #if defined(WIN32)
714 engageWin32LibraryDeinit();
715 #endif
716 */
717}
718
719//--------------------------------------------------------
720NAN_METHOD(start)
721{
722 NANRETI(engageStart());
723}
724
725//--------------------------------------------------------
726NAN_METHOD(stop)
727{
728 NANRETI(engageStop());
729}
730
731//--------------------------------------------------------
732NAN_METHOD(createGroup)
733{
734 NANRETI(engageCreateGroup(STRVAL(0)));
735}
736
737//--------------------------------------------------------
738NAN_METHOD(deleteGroup)
739{
740 NANRETI(engageDeleteGroup(STRVAL(0)));
741}
742
743//--------------------------------------------------------
744NAN_METHOD(joinGroup)
745{
746 NANRETI(engageJoinGroup(STRVAL(0)));
747}
748
749//--------------------------------------------------------
750NAN_METHOD(leaveGroup)
751{
752 NANRETI(engageLeaveGroup(STRVAL(0)));
753}
754
755//--------------------------------------------------------
756NAN_METHOD(setGroupRules)
757{
758 NANRETI(engageSetGroupRules(STRVAL(0), STRVAL(1)));
759}
760
761//--------------------------------------------------------
762NAN_METHOD(beginGroupTx)
763{
764 NANRETI(engageBeginGroupTx(STRVAL(0), INTVAL(1), INTVAL(2)));
765}
766
767//--------------------------------------------------------
768NAN_METHOD(beginGroupTxAdvanced)
769{
770 NANRETI(engageBeginGroupTxAdvanced(STRVAL(0), STRVAL(1)));
771}
772
773//--------------------------------------------------------
774NAN_METHOD(endGroupTx)
775{
776 NANRETI(engageEndGroupTx(STRVAL(0)));
777}
778
779//--------------------------------------------------------
780NAN_METHOD(setGroupRxTag)
781{
782 NANRETI(engageSetGroupRxTag(STRVAL(0), INTVAL(1)));
783}
784
785//--------------------------------------------------------
786NAN_METHOD(muteGroupRx)
787{
788 NANRETI(engageMuteGroupRx(STRVAL(0)));
789}
790
791//--------------------------------------------------------
792NAN_METHOD(unmuteGroupRx)
793{
794 NANRETI(engageUnmuteGroupRx(STRVAL(0)));
795}
796
797//--------------------------------------------------------
798NAN_METHOD(muteGroupTx)
799{
800 NANRETI(engageMuteGroupTx(STRVAL(0)));
801}
802
803//--------------------------------------------------------
804NAN_METHOD(unmuteGroupTx)
805{
806 NANRETI(engageUnmuteGroupTx(STRVAL(0)));
807}
808
809//--------------------------------------------------------
810NAN_METHOD(setGroupRxVolume)
811{
812 NANRETI(engageSetGroupRxVolume(STRVAL(0), INTVAL(1), INTVAL(2)));
813}
814
815//--------------------------------------------------------
816NAN_METHOD(updatePresenceDescriptor)
817{
818 NANRETI(engageUpdatePresenceDescriptor(STRVAL(0), STRVAL(1), INTVAL(0)));
819}
820
821//--------------------------------------------------------
822NAN_METHOD(encrypt)
823{
824 uint8_t* inputBytes = (uint8_t*) node::Buffer::Data(info[0]);
825
826 size_t inputOfs = INTVAL(1);
827 size_t inputLen = INTVAL(2);
828
829 // Our output is going to contain encrypted data padded to 16 bytes + another 16 bytes of IV
830 uint8_t *outputBytes = new uint8_t[inputLen + 16 * 2];
831
832 int bytesInOutput = engageEncrypt(inputBytes + inputOfs, inputLen, outputBytes, STRVAL(3));
833
834 if(bytesInOutput > 0)
835 {
836 info.GetReturnValue().Set(Nan::CopyBuffer((char*)outputBytes, bytesInOutput).ToLocalChecked());
837 }
838
839 delete[] outputBytes;
840}
841
842//--------------------------------------------------------
843NAN_METHOD(decrypt)
844{
845 uint8_t* inputBytes = (uint8_t*) node::Buffer::Data(info[0]);
846
847 size_t inputOfs = INTVAL(1);
848 size_t inputLen = INTVAL(2);
849
850 // Our output is not going to be larger than the input (if anything, it'll be smaller)
851 uint8_t *outputBytes = new uint8_t[inputLen];
852
853 int bytesInOutput = engageDecrypt(inputBytes + inputOfs, inputLen, outputBytes, STRVAL(3));
854
855 if(bytesInOutput > 0)
856 {
857 info.GetReturnValue().Set(Nan::CopyBuffer((char*)outputBytes, bytesInOutput).ToLocalChecked());
858 }
859
860 delete[] outputBytes;
861}
862
863//--------------------------------------------------------
864NAN_METHOD(getVersion)
865{
866 const char *rc = engageGetVersion();
867
868 if(rc == nullptr)
869 {
870 rc = "";
871 }
872
873 NANRETS(rc);
874}
875
876//--------------------------------------------------------
877NAN_METHOD(getHardwareReport)
878{
879 const char *rc = engageGetHardwareReport();
880
881 if(rc == nullptr)
882 {
883 rc = "";
884 }
885
886 NANRETS(rc);
887}
888
889//--------------------------------------------------------
890NAN_METHOD(getActiveLicenseDescriptor)
891{
892 const char *rc = engageGetActiveLicenseDescriptor();
893
894 if(rc == nullptr)
895 {
896 rc = "";
897 }
898
899 NANRETS(rc);
900}
901
902//--------------------------------------------------------
903NAN_METHOD(getLicenseDescriptor)
904{
905 const char *rc = engageGetLicenseDescriptor(STRVAL(0), STRVAL(1), STRVAL(2), STRVAL(3));
906
907 if(rc == nullptr)
908 {
909 rc = "";
910 }
911
912 NANRETS(rc);
913}
914
915//--------------------------------------------------------
916NAN_METHOD(updateLicense)
917{
918 NANRETI(engageUpdateLicense(STRVAL(0), STRVAL(1), STRVAL(2), STRVAL(3)));
919}
920
921// TODO: engageSendGroupRtp
922// TODO: engageRegisterGroupRtpHandler
923// TODO: engageUnregisterGroupRtpHandler
924// TODO: engageSendGroupBlob
925// TODO: engageSendGroupRaw
926// TODO: engagePlatformServiceDiscovered
927// TODO: engagePlatformServiceRediscovered
928// TODO: engagePlatformServiceUndiscovered
929
930//--------------------------------------------------------
931NAN_METHOD(queryGroupTimeline)
932{
933 NANRETI(engageQueryGroupTimeline(STRVAL(0), STRVAL(1)));
934}
935
936//--------------------------------------------------------
937NAN_METHOD(queryGroupHealth)
938{
939 NANRETI(engageQueryGroupHealth(STRVAL(0)));
940}
941
942//--------------------------------------------------------
943NAN_METHOD(queryGroupStats)
944{
945 NANRETI(engageQueryGroupStats(STRVAL(0)));
946}
947
948//--------------------------------------------------------
949NAN_METHOD(getNetworkInterfaceDevices)
950{
951 const char *rc = engageGetNetworkInterfaceDevices();
952
953 if(rc == nullptr)
954 {
955 rc = "";
956 }
957
958 NANRETS(rc);
959}
960
961//--------------------------------------------------------
962NAN_METHOD(getAudioDevices)
963{
964 const char *rc = engageGetAudioDevices();
965
966 if(rc == nullptr)
967 {
968 rc = "";
969 }
970
971 NANRETS(rc);
972}
973
974//--------------------------------------------------------
975NAN_METHOD(generateMission)
976{
977 const char *rc = engageGenerateMission(STRVAL(0), INTVAL(1), STRVAL(2), STRVAL(3));
978
979 if(rc == nullptr)
980 {
981 rc = "";
982 }
983
984 NANRETS(rc);
985}
986
987//--------------------------------------------------------
988NAN_METHOD(generateMissionUsingCertStore)
989{
990 const char *rc = engageGenerateMissionUsingCertStore(STRVAL(0), INTVAL(1), STRVAL(2), STRVAL(3), STRVAL(4), STRVAL(5), STRVAL(6));
991
992 if(rc == nullptr)
993 {
994 rc = "";
995 }
996
997 NANRETS(rc);
998}
999
1000//--------------------------------------------------------
1001NAN_METHOD(setMissionId)
1002{
1003 NANRETI(engageSetMissionId(STRVAL(0)));
1004}
1005
1006//--------------------------------------------------------
1007NAN_METHOD(openCertStore)
1008{
1009 NANRETI(engageOpenCertStore(STRVAL(0), STRVAL(1)));
1010}
1011
1012//--------------------------------------------------------
1013NAN_METHOD(closeCertStore)
1014{
1015 NANRETI(engageCloseCertStore());
1016}
1017
1018//--------------------------------------------------------
1019NAN_METHOD(setCertStoreCertificatePem)
1020{
1021 NANRETI(engageSetCertStoreCertificatePem(STRVAL(0), STRVAL(1), STRVAL(2), STRVAL(3)));
1022}
1023
1024//--------------------------------------------------------
1025NAN_METHOD(setCertStoreCertificateP12)
1026{
1027 NANRETI(engageSetCertStoreCertificateP12(STRVAL(0), (uint8_t*) node::Buffer::Data(info[1]), INTVAL(2), STRVAL(3), STRVAL(4)));
1028}
1029
1030//--------------------------------------------------------
1031NAN_METHOD(deleteCertStoreCertificate)
1032{
1033 NANRETI(engageDeleteCertStoreCertificate(STRVAL(0)));
1034}
1035
1036//--------------------------------------------------------
1037NAN_METHOD(getCertStoreCertificatePem)
1038{
1039 const char *rc = engageGetCertStoreCertificatePem(STRVAL(0));
1040
1041 if(rc == nullptr)
1042 {
1043 rc = "";
1044 }
1045
1046 NANRETS(rc);
1047}
1048
1049//--------------------------------------------------------
1050NAN_METHOD(getArrayOfCertificateDescriptorsFromPem)
1051{
1052 const char *rc = engageGetArrayOfCertificateDescriptorsFromPem(STRVAL(0));
1053
1054 if(rc == nullptr)
1055 {
1056 rc = "";
1057 }
1058
1059 NANRETS(rc);
1060}
1061
1062//--------------------------------------------------------
1063NAN_METHOD(getCertificateDescriptorFromPem)
1064{
1065 const char *rc = engageGetCertificateDescriptorFromPem(STRVAL(0));
1066
1067 if(rc == nullptr)
1068 {
1069 rc = "";
1070 }
1071
1072 NANRETS(rc);
1073}
1074
1075//--------------------------------------------------------
1076NAN_METHOD(importCertStoreElementFromCertStore)
1077{
1078 NANRETI(engageImportCertStoreElementFromCertStore(STRVAL(0), STRVAL(1), STRVAL(2), STRVAL(3), STRVAL(4)));
1079}
1080
1081//--------------------------------------------------------
1082NAN_METHOD(queryCertStoreContents)
1083{
1084 const char *rc = engageQueryCertStoreContents(STRVAL(0), STRVAL(1));
1085
1086 if(rc == nullptr)
1087 {
1088 rc = "";
1089 }
1090
1091 NANRETS(rc);
1092}
1093
1094//--------------------------------------------------------
1095NAN_METHOD(setCertStoreCertificateTags)
1096{
1097 NANRETI(engageSetCertStoreCertificateTags(STRVAL(0), STRVAL(1)));
1098}
1099
1100
1101//--------------------------------------------------------
1102NAN_METHOD(logMsg)
1103{
1104 NANRETI(engageLogMsg(INTVAL(0), STRVAL(1), STRVAL(2)));
1105}
1106
1107//--------------------------------------------------------
1108NAN_METHOD(platformNotifyChanges)
1109{
1110 NANRETI(engagePlatformNotifyChanges(STRVAL(0)));
1111}
1112
1113//--------------------------------------------------------
1114static void internalEngageLoggingHook(int level, const char *tag, const char *message)
1115{
1116 if(g_loggingHookFn.empty())
1117 {
1118 return;
1119 }
1120
1121 CrossThreadCallbackWorker *cbw = getCallback(g_loggingHookFn.c_str());
1122 if(!cbw)
1123 {
1124 return;
1125 }
1126
1127 std::vector<CrossThreadCallbackWorker::Parameter*> *params = new std::vector<CrossThreadCallbackWorker::Parameter*>();
1128 params->push_back(new CrossThreadCallbackWorker::IntParameter(level));
1129 params->push_back(new CrossThreadCallbackWorker::StringParameter(tag));
1130 params->push_back(new CrossThreadCallbackWorker::StringParameter(message));
1131 cbw->enqueue(params);
1132
1133 cbw->RELEASE_OBJECT_REFERENCE();
1134}
1135
1136//--------------------------------------------------------
1137NAN_METHOD(hookEngineLogging)
1138{
1139 g_loggingHookFn = STRVAL(0);
1140
1141 if(!g_loggingHookFn.empty())
1142 {
1143 engageSetLoggingOutputOverride(internalEngageLoggingHook);
1144 }
1145 else
1146 {
1148 }
1149}
1150
1151//--------------------------------------------------------
1152NAN_METHOD(setFipsCrypto)
1153{
1154 NANRETI(engageSetFipsCrypto(STRVAL(0)));
1155}
1156
1157//--------------------------------------------------------
1158NAN_METHOD(isCryptoFipsValidated)
1159{
1160 NANRETI(engageIsCryptoFipsValidated());
1161}
1162
1163//--------------------------------------------------------
1164NAN_METHOD(setCertStore)
1165{
1166 NANRETI(engageSetCertStore((uint8_t*) node::Buffer::Data(info[0]), INTVAL(1), STRVAL(2)));
1167}
1168
1169//--------------------------------------------------------
1170NAN_METHOD(getDeviceId)
1171{
1172 const char *rc = engageGetDeviceId();
1173
1174 if(rc == nullptr)
1175 {
1176 rc = "";
1177 }
1178
1179 NANRETS(rc);
1180}
1181
1182
1183//--------------------------------------------------------
1184NAN_METHOD(verifyRiff)
1185{
1186 NANRETI(engageVerifyRiff(STRVAL(0)));
1187}
1188
1189
1190//--------------------------------------------------------
1191NAN_METHOD(getRiffDescriptor)
1192{
1193 const char *rc = engageGetRiffDescriptor(STRVAL(0));
1194
1195 if(rc == nullptr)
1196 {
1197 rc = "";
1198 }
1199
1200 NANRETS(rc);
1201}
1202
1203
1204//--------------------------------------------------------
1205NAN_MODULE_INIT(Init)
1206{
1207 ENGAGE_BINDING(on);
1208
1209 ENGAGE_BINDING(setLogLevel);
1210
1211 ENGAGE_BINDING(enableCallbacks);
1212 ENGAGE_BINDING(disableCallbacks);
1213
1214 ENGAGE_BINDING(initialize);
1215 ENGAGE_BINDING(shutdown);
1216
1217 ENGAGE_BINDING(start);
1218 ENGAGE_BINDING(stop);
1219
1220 ENGAGE_BINDING(createGroup);
1221 ENGAGE_BINDING(deleteGroup);
1222 ENGAGE_BINDING(joinGroup);
1223 ENGAGE_BINDING(leaveGroup);
1224 ENGAGE_BINDING(setGroupRules);
1225
1226 ENGAGE_BINDING(beginGroupTx);
1227 ENGAGE_BINDING(beginGroupTxAdvanced);
1228 ENGAGE_BINDING(endGroupTx);
1229 ENGAGE_BINDING(setGroupRxTag);
1230
1231 ENGAGE_BINDING(muteGroupRx);
1232 ENGAGE_BINDING(unmuteGroupRx);
1233
1234 ENGAGE_BINDING(muteGroupTx);
1235 ENGAGE_BINDING(unmuteGroupTx);
1236
1237 ENGAGE_BINDING(setGroupRxVolume);
1238
1239 ENGAGE_BINDING(queryGroupTimeline);
1240
1241 ENGAGE_BINDING(updatePresenceDescriptor);
1242
1243 ENGAGE_BINDING(encrypt);
1244 ENGAGE_BINDING(decrypt);
1245
1246 ENGAGE_BINDING(updateLicense);
1247 ENGAGE_BINDING(getVersion);
1248 ENGAGE_BINDING(getHardwareReport);
1249 ENGAGE_BINDING(getNetworkInterfaceDevices);
1250 ENGAGE_BINDING(getAudioDevices);
1251
1252 ENGAGE_BINDING(getActiveLicenseDescriptor);
1253 ENGAGE_BINDING(getLicenseDescriptor);
1254
1255 ENGAGE_BINDING(openCertStore);
1256 ENGAGE_BINDING(closeCertStore);
1257 ENGAGE_BINDING(setCertStore);
1258 ENGAGE_BINDING(setCertStoreCertificatePem);
1259 ENGAGE_BINDING(setCertStoreCertificateP12);
1260 ENGAGE_BINDING(deleteCertStoreCertificate);
1261 ENGAGE_BINDING(getCertStoreCertificatePem);
1262 ENGAGE_BINDING(getCertificateDescriptorFromPem);
1263 ENGAGE_BINDING(importCertStoreElementFromCertStore);
1264 ENGAGE_BINDING(queryCertStoreContents);
1265 ENGAGE_BINDING(setCertStoreCertificateTags);
1266
1267 ENGAGE_BINDING(generateMission);
1268 ENGAGE_BINDING(generateMissionUsingCertStore);
1269
1270 ENGAGE_BINDING(setMissionId);
1271 ENGAGE_BINDING(platformNotifyChanges);
1272
1273 ENGAGE_BINDING(logMsg);
1274 ENGAGE_BINDING(hookEngineLogging);
1275
1276 ENGAGE_BINDING(setFipsCrypto);
1277 ENGAGE_BINDING(isCryptoFipsValidated);
1278
1279 ENGAGE_BINDING(getDeviceId);
1280
1281 ENGAGE_BINDING(verifyRiff);
1282 ENGAGE_BINDING(getRiffDescriptor);
1283}
1284
1285NODE_MODULE(engage, Init)
API functions, codes, and more.
ENGAGE_API int engageMuteGroupRx(const char *_Nonnull id)
[ASYNC] Mutes play-out of received audio
ENGAGE_API int engageShutdown()
[SYNC] Shuts down the Engine
ENGAGE_API const char *_Nonnull engageGetLicenseDescriptor(const char *_Nonnull entitlement, const char *_Nonnull key, const char *_Nullable activationCode, const char *_Nullable manufacturerId)
[SYNC] Returns a license descriptor for the parameters passed in
ENGAGE_API int engageQueryGroupStats(const char *_Nonnull id)
[ASYNC] Requests that the Engine deliver a statistics report for the group
ENGAGE_API int engageSetCertStore(const uint8_t *_Nonnull buffer, size_t size, const char *_Nullable passwordHexByteString)
[SYNC] Set the certstore content via buffer
ENGAGE_API int engageDeleteGroup(const char *_Nonnull id)
[ASYNC] Deletes a previously-created group object
ENGAGE_API int engageIsCryptoFipsValidated(void)
[SYNC] Returns 1 if crypto is FIPS140-2 validated, otherwise 0
ENGAGE_API int engageSetFipsCrypto(const char *_Nonnull jsonParams)
[SYNC] Enable FIPS crypto
ENGAGE_API int engageVerifyRiff(const char *_Nonnull fn)
[SYNC] Verifies a recorded RIFF file.
ENGAGE_API int engageRegisterEventCallbacks(const EngageEvents_t *_Nonnull pEvents)
[SYNC] Registers application event handlers with the Engine
ENGAGE_API int engageQueryGroupTimeline(const char *_Nonnull id, const char *_Nonnull jsonParams)
[ASYNC] Requests that the Engine deliver a timeline report for the group
ENGAGE_API int engageSetGroupRxVolume(const char *_Nonnull id, int left, int right)
[ASYNC] Sets the audio play-out volume of the group
ENGAGE_API int engageEndGroupTx(const char *_Nonnull id)
[ASYNC] Ends transmission on an audio group
ENGAGE_API int engagePlatformNotifyChanges(const char *_Nonnull jsonChangesArray)
[SYNC] Notifies Engage of changes reported by the application or platform
ENGAGE_API int engageStop(void)
[ASYNC] Stops the Engine's internal processing
ENGAGE_API const char *_Nonnull engageGetCertStoreCertificatePem(const char *_Nonnull id)
[SYNC] Returns a certificate in PEM format. The private key (if any) is NOT returned.
ENGAGE_API int engageEnableSyslog(int enable)
[SYNC] Enables or disables logging to syslog.
ENGAGE_API int engageCloseCertStore(void)
[SYNC] Closes the current certificate store (if any)
ENGAGE_API const char *_Nonnull engageGetDeviceId()
[SYNC] Returns the device identifier
ENGAGE_API int engageLogMsg(int level, const char *_Nonnull tag, const char *_Nonnull msg)
[SYNC] Log a message via the Engine's logger
ENGAGE_API int engageJoinGroup(const char *_Nonnull id)
[ASYNC] Joins a group
ENGAGE_API int engageSetGroupRules(const char *_Nonnull id, const char *_Nonnull jsonParams)
[ASYNC] Sets the audio play-out volume of the group
ENGAGE_API const char *_Nonnull engageGetHardwareReport()
[SYNC] Returns a hardware report
ENGAGE_API const char *_Nonnull engageGetArrayOfCertificateDescriptorsFromPem(const char *_Nonnull pem)
[SYNC] Returns a JSON array, with each element being an object describing the certificate PEM.
ENGAGE_API int engageQueryGroupHealth(const char *_Nonnull id)
[ASYNC] Requests that the Engine deliver a health report for the group
ENGAGE_API int engageImportCertStoreElementFromCertStore(const char *_Nonnull id, const char *_Nonnull srcId, const char *_Nonnull srcFileName, const char *_Nonnull srcPasswordHexByteString, const char *_Nullable tags)
[SYNC] Adds/updates an element (certificate and optionally private key) from another certificate stor...
ENGAGE_API int engageSetCertStoreCertificateP12(const char *_Nonnull id, uint8_t *_Nonnull data, size_t size, const char *_Nullable password, const char *_Nullable tags)
[SYNC] Adds/updates a certificate and (optionally) private key using P12 content
ENGAGE_API int engageMuteGroupTx(const char *_Nonnull id)
[ASYNC] Mutes microphone audio capture
ENGAGE_API int engageSetGroupRxTag(const char *_Nonnull id, uint16_t tag)
[ASYNC] Sets/clear a audio stream subchannel tag
ENGAGE_API int engageEnableWatchdog(int enable)
[SYNC] Enables or disables the Engine watchdog.
ENGAGE_API int engageOpenCertStore(const char *_Nonnull fileName, const char *_Nullable passwordHexByteString)
[SYNC] Opens a certificate store
ENGAGE_API const char *_Nonnull engageGenerateMission(const char *_Nonnull keyPhrase, int audioGroupCount, const char *_Nullable rallypointHost, const char *_Nullable missionName)
[SYNC] Generates a mission based on a key phrase
ENGAGE_API const char *_Nonnull engageGetRiffDescriptor(const char *_Nonnull fn)
[SYNC] Returns a descriptor for a RIFF file
ENGAGE_API int engageBeginGroupTxAdvanced(const char *_Nonnull id, const char *_Nonnull jsonParams)
[ASYNC] Begin audio transmission on a group with additional parameters
ENGAGE_API int engageDecrypt(const uint8_t *_Nonnull src, size_t size, uint8_t *_Nonnull dst, const char *_Nonnull passwordHexByteString)
[SYNC] Decrypt data using the Engine's cryptography module
ENGAGE_API int engageBeginGroupTx(const char *_Nonnull id, int txPriority, uint32_t txFlags)
[ASYNC] Begin audio transmission on a group
ENGAGE_API int engageInitialize(const char *_Nullable enginePolicyConfiguration, const char *_Nullable userIdentity, const char *_Nullable tempStoragePath)
[SYNC] Initializes the Engine.
ENGAGE_API const char *_Nonnull engageGetNetworkInterfaceDevices()
[SYNC] Returns an array of network interface devices in JSON format
ENGAGE_API int engageSetLoggingOutputOverride(const _Nullable PFN_ENGAGE_LOG_HOOK pfnHook)
[SYNC] Sets/clears the output override callback for log messages.
ENGAGE_API const char *_Nonnull engageGetActiveLicenseDescriptor()
[SYNC] Returns the currently-active license descriptor
ENGAGE_API int engageCreateGroup(const char *_Nonnull jsonConfiguration)
[ASYNC] Creates a group object
ENGAGE_API int engageUpdatePresenceDescriptor(const char *_Nonnull id, const char *_Nonnull descriptorJson, int forceBeacon)
[ASYNC] Updates the application-defined elements of a presence descriptor
ENGAGE_API int engageEncrypt(const uint8_t *_Nonnull src, size_t size, uint8_t *_Nonnull dst, const char *_Nonnull passwordHexByteString)
[SYNC] Encrypt data using the Engine's cryptography module
ENGAGE_API int engageUnmuteGroupTx(const char *_Nonnull id)
[ASYNC] Unmutes microphone audio capture
ENGAGE_API const char *_Nonnull engageGetVersion()
[SYNC] Returns the version of the Engine
ENGAGE_API const char *_Nonnull engageGetCertificateDescriptorFromPem(const char *_Nonnull pem)
[SYNC] Returns a JSON object describing the certificate PEM.
ENGAGE_API int engageSetCertStoreCertificateTags(const char *_Nonnull id, const char *_Nullable tags)
[SYNC] Updates a certificate's tags
ENGAGE_API int engageLeaveGroup(const char *_Nonnull id)
[ASYNC] Leaves a group
ENGAGE_API int engageSetLogLevel(int level)
[SYNC] Sets the Engine's logging level.
ENGAGE_API int engageSetCertStoreCertificatePem(const char *_Nonnull id, const char *_Nonnull certificatePem, const char *_Nullable privateKeyPem, const char *_Nullable tags)
[SYNC] Adds/updates a certificate and (optionally) private key using PEM strings
ENGAGE_API int engageSetLogTagExtension(const char *_Nullable tagExtension)
[SYNC] Sets the Engine's log tag extension.
ENGAGE_API const char *_Nonnull engageGenerateMissionUsingCertStore(const char *_Nonnull keyPhrase, int audioGroupCount, const char *_Nullable rallypointHost, const char *_Nullable missionName, const char *_Nonnull certStoreFn, const char *_Nullable certStorePasswordHexByteString, const char *_Nullable certStoreElement)
[SYNC] Generates a mission based on a key phrase and using a specified certificate store
ENGAGE_API int engageUpdateLicense(const char *_Nonnull entitlement, const char *_Nonnull key, const char *_Nullable activationCode, const char *_Nullable manufacturerId)
[ASYNC] Update the active license with new parameters
ENGAGE_API const char *_Nonnull engageQueryCertStoreContents(const char *_Nonnull fileName, const char *_Nullable passwordHexByteString)
[SYNC] Returns an extended descriptor of named certificate store
ENGAGE_API const char *_Nonnull engageGetAudioDevices()
[SYNC] Returns an array of audio device descriptor interface devices in JSON format
ENGAGE_API int engageSetMissionId(const char *_Nullable missionId)
[SYNC] Sets the (optional) mission ID for the Engine
ENGAGE_API int engageStart(void)
[ASYNC] Starts the Engine
ENGAGE_API int engageDeleteCertStoreCertificate(const char *_Nonnull id)
[SYNC] Deletes a certificate and its private key (if any)
ENGAGE_API int engageUnmuteGroupRx(const char *_Nonnull id)
[ASYNC] Unmutes play-out of received audio
static const int ENGAGE_RESULT_OK
The request was succesful.
static const int ENGAGE_SYSLOG_ENABLE
Enables syslog output on supported systems.
static const int ENGAGE_SYSLOG_DISABLE
Disables syslog output.
static const int ENGAGE_WATCHDOG_DISABLE
Disables the watchdog - has no effect if the watchdog is disabled in the policy configuration.
static const int ENGAGE_WATCHDOG_ENABLE
Enables the watchdog - has no effect if the watchdog is disabled in the policy configuration.
Event Handlers Struct.