18 #if !defined(NTV2_PREVENT_PLUGIN_LOAD) 22 #include "mbedtls/x509.h" 23 #include "mbedtls/error.h" 24 #include "mbedtls/md.h" 25 #include "mbedtls/ssl.h" 26 #endif // defined(NTV2_PREVENT_PLUGIN_LOAD) 28 #include <CoreFoundation/CoreFoundation.h> 30 #define DLL_EXTENSION ".dylib" 31 #define PATH_DELIMITER "/" 32 #define FIRMWARE_FOLDER "Firmware" 33 #elif defined(AJALinux) 35 #define DLL_EXTENSION ".so" 36 #define PATH_DELIMITER "/" 37 #define FIRMWARE_FOLDER "firmware" 38 #elif defined(MSWindows) 39 #define DLL_EXTENSION ".dll" 40 #define PATH_DELIMITER "\\" 41 #define FIRMWARE_FOLDER "Firmware" 42 #elif defined(AJABareMetal) 43 #define DLL_EXTENSION ".so" 44 #define PATH_DELIMITER "/" 45 #define FIRMWARE_FOLDER "firmware" 47 #define SIG_EXTENSION ".sig" 51 #define INSTP(_p_) xHEX0N(uint64_t(_p_),16) 52 #define NBFAIL(__x__) AJA_sERROR (AJA_DebugUnit_RPCClient, INSTP(this) << "::" << AJAFUNC << ": " << __x__) 53 #define NBWARN(__x__) AJA_sWARNING(AJA_DebugUnit_RPCClient, INSTP(this) << "::" << AJAFUNC << ": " << __x__) 54 #define NBNOTE(__x__) AJA_sNOTICE (AJA_DebugUnit_RPCClient, INSTP(this) << "::" << AJAFUNC << ": " << __x__) 55 #define NBINFO(__x__) AJA_sINFO (AJA_DebugUnit_RPCClient, INSTP(this) << "::" << AJAFUNC << ": " << __x__) 56 #define NBDBG(__x__) AJA_sDEBUG (AJA_DebugUnit_RPCClient, INSTP(this) << "::" << AJAFUNC << ": " << __x__) 57 #define NBCFAIL(__x__) AJA_sERROR (AJA_DebugUnit_RPCClient, AJAFUNC << ": " << __x__) 58 #define NBCWARN(__x__) AJA_sWARNING(AJA_DebugUnit_RPCClient, AJAFUNC << ": " << __x__) 59 #define NBCNOTE(__x__) AJA_sNOTICE (AJA_DebugUnit_RPCClient, AJAFUNC << ": " << __x__) 60 #define NBCINFO(__x__) AJA_sINFO (AJA_DebugUnit_RPCClient, AJAFUNC << ": " << __x__) 61 #define NBCDBG(__x__) AJA_sDEBUG (AJA_DebugUnit_RPCClient, AJAFUNC << ": " << __x__) 62 #define NBSFAIL(__x__) AJA_sERROR (AJA_DebugUnit_RPCServer, AJAFUNC << ": " << __x__) 63 #define NBSWARN(__x__) AJA_sWARNING(AJA_DebugUnit_RPCServer, AJAFUNC << ": " << __x__) 64 #define NBSNOTE(__x__) AJA_sNOTICE (AJA_DebugUnit_RPCServer, AJAFUNC << ": " << __x__) 65 #define NBSINFO(__x__) AJA_sINFO (AJA_DebugUnit_RPCServer, AJAFUNC << ": " << __x__) 66 #define NBSDBG(__x__) AJA_sDEBUG (AJA_DebugUnit_RPCServer, AJAFUNC << ": " << __x__) 68 #define PLGFAIL(__x__) AJA_sERROR (AJA_DebugUnit_Plugins, AJAFUNC << ": " << __x__) 69 #define PLGWARN(__x__) AJA_sWARNING(AJA_DebugUnit_Plugins, AJAFUNC << ": " << __x__) 70 #define PLGNOTE(__x__) AJA_sNOTICE (AJA_DebugUnit_Plugins, AJAFUNC << ": " << __x__) 71 #define PLGINFO(__x__) AJA_sINFO (AJA_DebugUnit_Plugins, AJAFUNC << ": " << __x__) 72 #define PLGDBG(__x__) AJA_sDEBUG (AJA_DebugUnit_Plugins, AJAFUNC << ": " << __x__) 74 #define P_FAIL(__x__) do \ 77 _os_ << AJAFUNC << ": " << __x__; \ 79 cout << "## ERROR: " << _os_.str() << endl; \ 80 AJA_sERROR (AJA_DebugUnit_Plugins, _os_.str()); \ 81 errMsg = _os_.str(); \ 83 #define P_WARN(__x__) if (useStdout()) cout << "## WARNING: " << AJAFUNC << ": " << __x__ << endl; \ 84 AJA_sWARNING(AJA_DebugUnit_Plugins, AJAFUNC << ": " << __x__) 85 #define P_NOTE(__x__) if (useStdout()) cout << "## NOTE: " << AJAFUNC << ": " << __x__ << endl; \ 86 AJA_sNOTICE (AJA_DebugUnit_Plugins, AJAFUNC << ": " << __x__) 87 #define P_INFO(__x__) if (useStdout()) cout << "## INFO: " << AJAFUNC << ": " << __x__ << endl; \ 88 AJA_sINFO (AJA_DebugUnit_Plugins, AJAFUNC << ": " << __x__) 89 #define P_DBG(__x__) if (useStdout()) cout << "## DEBUG: " << AJAFUNC << ": " << __x__ << endl; \ 90 AJA_sDEBUG (AJA_DebugUnit_Plugins, AJAFUNC << ": " << __x__) 92 #if defined(_DEBUGSTATS_) 93 #define PDBGX(__x__) AJA_sDEBUG (AJA_DebugUnit_Plugins, INSTP(this) << "::" << AJAFUNC << ": " << __x__) 115 if (it == mDict.end())
122 string str(valueForKey(inKey));
125 if (str.find(
"0x") == 0 || str.find(
"0X") == 0)
132 if (str.find(
"x") == 0 || str.find(
"X") == 0)
139 if (str.find(
"o") == 0 || str.find(
"O") == 0)
146 if (str.find(
"b") == 0 || str.find(
"B") == 0)
161 const string & key(it->first), val(it->second), quote(val.find(
' ') != string::npos ?
"'" :
"");
162 oss << key <<
"=" << quote << val << quote;
163 if (++it != mDict.end())
170 const int kyWdth(
int(largestKeySize()+0)), valWdth(
int(largestValueSize()+0));
171 oss << string(
size_t(kyWdth),
'-') <<
" " << string(
size_t(valWdth),
'-') << endl;
174 const string & key(it->first), val(it->second);
175 oss << std::setw(kyWdth) << key <<
" : " << val;
176 if (++it != mDict.end())
185 size_t badKVPairs(0), insertFailures(0);
191 if (keyValPair.size() != 2)
192 {badKVPairs++;
continue;}
193 const string k(keyValPair.at(0)), v(keyValPair.at(1));
197 return !empty() && !badKVPairs && !insertFailures;
206 oss << it->first <<
"\t" << it->second;
207 if (++it != mDict.end())
211 return !outStr.empty();
217 for (
DictConstIter it(mDict.begin()); it != mDict.end(); ++it)
218 result.insert(it->first);
225 for (
DictConstIter it(mDict.begin()); it != mDict.end(); ++it)
226 if (it->first.length() > result)
227 result = it->first.length();
234 for (
DictConstIter it(mDict.begin()); it != mDict.end(); ++it)
235 if (it->second.length() > result)
236 result = it->second.length();
244 if (inKey.find(
"\t") != string::npos)
246 if (inKey.find(
"\n") != string::npos)
248 if (inValue.find(
"\t") != string::npos)
250 if (inValue.find(
"\n") != string::npos)
253 mDict[inKey] = inValue;
254 }
catch (
const bad_alloc &) {
264 size_t numUpdated(0);
265 for (
DictConstIter it(inDict.mDict.begin()); it != inDict.mDict.end(); ++it)
266 if (hasKey(it->first))
267 {mDict[it->first] = it->second; numUpdated++;}
274 for (
DictConstIter it(inDict.mDict.begin()); it != inDict.mDict.end(); ++it)
275 if (!hasKey(it->first))
276 {mDict[it->first] = it->second; numAdded++;}
290 mQueryParams.clear();
302 if (!inStripLeadSlash)
304 if (rsrc.at(0) ==
'/')
311 string result(Host()), port(Port());
315 result +=
":" + port;
319 void NTV2DeviceSpecParser::Parse (
void)
328 string tokDevID, tokIndexNum, tokScheme, tokSerial, tokModelName, tokIPV4, tokPortNum;
329 size_t posDevID(0), posIndexNum(0), posScheme(0), posSerial(0), posModelName(0), posNetAddr(0);
330 bool isSerial(ParseSerialNum(posSerial, tokSerial)), isScheme(ParseScheme(posScheme, tokScheme));
331 bool isIndexNum(ParseDecNumber(posIndexNum, tokIndexNum)), isDeviceID(ParseDeviceID(posDevID, tokDevID));
332 bool isModelName(ParseModelName(posModelName, tokModelName));
333 bool isIPV4Port(ParseHostAddressAndPortNumber(posNetAddr, tokIPV4, tokPortNum));
336 posDevID = posIndexNum = posSerial = posModelName = posScheme;
337 isSerial = ParseSerialNum(posSerial, tokSerial);
338 isIndexNum = ParseDecNumber(posIndexNum, tokIndexNum);
339 isDeviceID = ParseDeviceID(posDevID, tokDevID);
340 isModelName = ParseModelName(posModelName, tokModelName);
343 if (isDeviceID) posQuery = posDevID;
344 else if (isSerial) posQuery = posSerial;
345 else if (isModelName) posQuery = posModelName;
346 else if (isIndexNum) posQuery = posIndexNum;
350 if (ParseQuery(posQuery, params))
353 mQueryParams = params;
355 if (isDeviceID) posDevID = mPos;
356 else if (isSerial) posSerial = mPos;
357 else if (isModelName) posModelName = mPos;
358 else if (isIndexNum) posIndexNum = mPos;
373 bool converted(
false);
375 if (tokSerial.length() == 18)
378 const bool hasLeading0X (tokSerial.find(
"0X") == 0 || tokSerial.find(
"0x") == 0);
379 const string hex64(tokSerial.substr(hasLeading0X ? 2 : 0, 16));
382 for (
size_t ndx(0); ndx < 8; ndx++)
383 serTxt +=
char(serNum64 >> ((7-ndx)*8));
389 for (
size_t ndx(0); ndx < tokSerial.length(); ndx++)
390 {
char ch(tokSerial.at(ndx));
391 if ( ! ( ( (ch >=
'0') && (ch <=
'9') ) ||
392 ( (ch >=
'A') && (ch <=
'Z') ) ||
393 ( (ch >=
'a') && (ch <=
'z') ) ||
394 (ch ==
' ') || (ch ==
'-') ) )
396 err <<
"Illegal serial number character '" << (ch ? ch :
'?') <<
"' (" <<
xHEX0N(
UWord(ch),2) <<
")";
398 mPos -= converted ? 16 : 8; mPos += ndx * (converted ? 2 : 1) + (converted ? 1 : 0);
415 if (posIndexNum < SpecLength())
417 if (isIPV4Port && !tokIPV4.empty())
422 if (!tokPortNum.empty())
426 err <<
"Extra characters past index number";
437 err <<
"Invalid local device specification";
439 mPos += isScheme ? 12 : 0;
450 size_t posURL(posScheme), posRsrc(0);
451 string host, port, rsrcPath;
452 if (!ParseHostAddressAndPortNumber(posURL, host, port))
453 {mPos = posURL; AddError(
"Bad host address or port number");
break;}
462 if (ParseResourcePath(posRsrc, rsrcPath))
465 size_t posQuery(mPos);
467 if (ParseQuery(posQuery, params))
470 mQueryParams = params;
475 if (mPos < SpecLength())
476 {err <<
"Parser failed at character position " <<
DEC(mPos); AddError(err.str());}
480 { oss <<
"NTV2DeviceSpecParser::Parse success: '" << DeviceSpec() <<
"' -- ";
485 { oss <<
"NTV2DeviceSpecParser::Parse failed: ";
489 #endif // defined(_DEBUG) 495 oss <<
"local device";
496 else if (HasScheme())
497 oss <<
"device '" << Scheme() <<
"'";
501 oss <<
" serial '" << DeviceSerial() <<
"'";
503 oss <<
" model '" << DeviceModel() <<
"'";
507 oss <<
" " << DeviceIndex();
517 {oss << endl; Results().Print(oss,
false);}
525 ostringstream result;
528 result <<
"ntv2local://";
530 result << DeviceSerial();
532 result << DeviceModel();
534 result << DeviceID();
536 result << DeviceIndex();
541 result << Scheme() <<
"://";
547 if (HasQueryParams())
549 string q (MakeQueryString(urlEncodeQuery));
561 MakeQueryString (mQueryParams, result);
575 if (devIDStr.find(
"0X") != string::npos)
590 oss <<
DEC(ErrorCount()) << (ErrorCount() == 1 ?
" error" :
" errors") << (HasErrors() ?
":" :
"");
594 << DeviceSpec() << endl
595 << string(mPos ? mPos : 0,
' ') <<
"^" << endl;
596 for (
size_t num(0); num < ErrorCount(); )
599 if (++num < ErrorCount())
606 bool NTV2DeviceSpecParser::ParseHexNumber (
size_t & pos,
string & outToken)
610 while (pos < SpecLength())
612 const char ch(CharAt(pos));
613 if (tokHexNum.length() == 0)
617 ++pos; tokHexNum = ch;
619 else if (tokHexNum.length() == 1)
621 if (ch !=
'x' && ch !=
'X')
623 ++pos; tokHexNum += ch;
629 ++pos; tokHexNum += ch;
632 if (tokHexNum.length() > 2)
633 {
aja::upper(tokHexNum); outToken = tokHexNum;}
634 return !outToken.empty();
637 bool NTV2DeviceSpecParser::ParseDecNumber (
size_t & pos,
string & outToken)
641 while (pos < SpecLength())
643 const char ch(CharAt(pos));
644 if (!IsDecimalDigit(ch))
647 if (ch !=
'0' || tokDecNum !=
"0")
650 if (tokDecNum.length() > 0)
651 outToken = tokDecNum;
652 return !outToken.empty();
655 bool NTV2DeviceSpecParser::ParseAlphaNum (
size_t & pos,
string & outToken,
const std::string & inOtherChars)
659 while (pos < SpecLength())
661 const char ch(CharAt(pos));
662 if (!IsLetter(ch) && !IsDecimalDigit(ch) && inOtherChars.find(ch) == string::npos)
664 if (tokAlphaNum.empty() && !IsLetter(ch))
666 ++pos; tokAlphaNum += ch;
668 if (tokAlphaNum.length() > 0)
669 outToken = tokAlphaNum;
670 return !outToken.empty();
673 bool NTV2DeviceSpecParser::ParseAlphaNumeric (
size_t & pos,
string & outToken,
const std::string & inOtherChars)
677 while (pos < SpecLength())
679 const char ch(CharAt(pos));
680 if (!IsLetter(ch) && !IsDecimalDigit(ch) && inOtherChars.find(ch) == string::npos)
682 ++pos; tokAlphaNum += ch;
684 if (tokAlphaNum.length() > 0)
685 outToken = tokAlphaNum;
686 return !outToken.empty();
689 bool NTV2DeviceSpecParser::ParseScheme (
size_t & pos,
string & outToken)
692 string rawScheme, tokScheme;
693 while (ParseAlphaNum(pos, rawScheme))
695 tokScheme = rawScheme;
696 char ch(CharAt(pos));
699 ++pos; tokScheme += ch;
704 ++pos; tokScheme += ch;
709 ++pos; tokScheme += ch;
712 if (tokScheme.find(
"://") != string::npos)
713 {
aja::lower(rawScheme); outToken = rawScheme;}
714 return !outToken.empty();
717 bool NTV2DeviceSpecParser::ParseSerialNum (
size_t & pos,
string & outToken)
720 string tokAlphaNum, tokHexNum;
721 size_t origPos(pos), posAlphaNum(pos), posHexNum(pos);
724 while (posAlphaNum < SpecLength())
726 const char ch(CharAt(posAlphaNum));
727 if (!IsUpperLetter(ch) && !IsLowerLetter(ch) && !IsDecimalDigit(ch) && ch !=
'-' && ch !=
' ')
729 ++posAlphaNum; tokAlphaNum += ch;
731 if (tokAlphaNum.length() < 2)
732 {tokAlphaNum.clear();
break;}
733 if (tokAlphaNum.length() == 8 || tokAlphaNum.length() == 9)
734 {pos = posAlphaNum; outToken = tokAlphaNum;
break;}
736 if (ParseHexNumber(posHexNum, tokHexNum))
737 if (tokHexNum.length() == 18)
738 {pos = posHexNum; outToken = tokHexNum;}
740 if (tokAlphaNum ==
"ntv2kona1" || tokAlphaNum ==
"ntv2vkona")
741 {outToken.clear(); pos = origPos;
return false;}
742 return !outToken.empty();
745 bool NTV2DeviceSpecParser::ParseDeviceID (
size_t & pos,
string & outToken)
749 if (!ParseHexNumber(pos, tokHexNum))
751 if (tokHexNum.length() != 10)
760 ostringstream devID; devID <<
xHEX0N(*it,8);
761 string devIDStr(devID.str());
763 devIDStrs.insert(devIDStr);
765 if (devIDStrs.find(tokHexNum) != devIDStrs.end())
766 outToken = tokHexNum;
767 return !outToken.empty();
770 bool NTV2DeviceSpecParser::ParseModelName (
size_t & pos,
string & outToken)
774 if (!ParseAlphaNum(pos, tokName,
" "))
785 modelNames.insert(modelName);
787 if (modelNames.find(tokName) != modelNames.end())
789 return !outToken.empty();
792 bool NTV2DeviceSpecParser::ParseDNSName (
size_t & pos,
string & outDNSName)
795 string dnsName, name;
798 while (ParseAlphaNum(dnsPos, name,
"_-"))
800 if (!dnsName.empty())
808 if (!dnsName.empty())
810 outDNSName = dnsName;
811 return !outDNSName.empty();
814 bool NTV2DeviceSpecParser::ParseIPv4Address (
size_t & pos,
string & outIPv4)
821 while (ParseDecNumber(ipv4Pos, num))
823 ipv4Name.push_back(num);
824 ch = CharAt(ipv4Pos);
829 if (ipv4Name.size() == 4)
832 return ipv4Name.size() == 4;
835 bool NTV2DeviceSpecParser::ParseHostAddressAndPortNumber (
size_t & pos,
string & outAddr,
string & outPort)
837 outAddr.clear(); outPort.clear();
839 string dnsName, ipv4, port;
840 size_t dnsPos(pos), ipv4Pos(pos), portPos(0);
841 bool isDNS(ParseDNSName(dnsPos, dnsName)), isIPv4(ParseIPv4Address(ipv4Pos, ipv4));
842 if (!isDNS && !isIPv4)
843 {pos = dnsPos < ipv4Pos ? ipv4Pos : dnsPos;
return false;}
846 {outAddr = ipv4; pos = portPos = ipv4Pos;}
848 {outAddr = dnsName; pos = portPos = dnsPos;}
851 char ch (CharAt(portPos));
855 if (!ParseDecNumber(portPos, port))
856 {pos = portPos;
return false;}
862 bool NTV2DeviceSpecParser::ParseResourcePath (
size_t & pos,
string & outRsrc)
867 char ch(CharAt(rsrcPos));
872 if (!ParseAlphaNumeric(rsrcPos, name,
" "))
875 ch = CharAt(rsrcPos);
880 return !outRsrc.empty();
883 bool NTV2DeviceSpecParser::ParseParamAssignment (
size_t & pos,
string & outKey,
string & outValue)
885 outKey.clear(); outValue.clear();
887 size_t paramPos(pos);
888 char ch(CharAt(paramPos));
890 ch = CharAt(++paramPos);
893 if (!ParseAlphaNumeric(paramPos, key,
"%"))
895 ch = CharAt(paramPos);
898 ch = CharAt(++paramPos);
899 while (ch != 0 && ch !=
'&')
902 ch = CharAt(++paramPos);
906 {pos = paramPos; outKey =
key; outValue =
value;}
910 bool NTV2DeviceSpecParser::ParseQuery (
size_t & pos,
NTV2Dictionary & outParams)
914 size_t queryPos(pos);
915 char ch(CharAt(queryPos));
920 while (ParseParamAssignment(queryPos, key, value))
922 outParams.
insert(key, value);
923 ch = CharAt(queryPos);
927 if (!outParams.
empty())
929 return !outParams.
empty();
937 if (!queryStr.empty())
938 if (queryStr[0] ==
'?')
940 PLGDBG(
"Query: '" << queryStr <<
"'");
944 string str(*it), key, value;
945 if (str.find(
"=") == string::npos)
948 outQueryParams.
insert(key, value);
949 PLGDBG(
"'" << key <<
"' = ''");
956 if (pieces.size() > 1)
957 value = pieces.at(1);
959 {
PLGWARN(
"Empty key '" << key <<
"'");
continue;}
960 if (outQueryParams.
hasKey(key))
961 PLGDBG(
"Param '" << key <<
"' value '" << outQueryParams.
valueForKey(key) <<
"' to be replaced with '" << value <<
"'");
971 if (inSrcDict.
empty())
977 const string key(*it);
985 params.push_back(oss.str());
993 bool NTV2DeviceSpecParser::IsUpperLetter (
const char inChar)
994 {
static const string sHexDigits(
"_ABCDEFGHIJKLMNOPQRSTUVWXYZ");
995 return sHexDigits.find(inChar) != string::npos;
998 bool NTV2DeviceSpecParser::IsLowerLetter (
const char inChar)
999 {
static const string sHexDigits(
"abcdefghijklmnopqrstuvwxyz");
1000 return sHexDigits.find(inChar) != string::npos;
1003 bool NTV2DeviceSpecParser::IsLetter (
const char inChar,
const bool inIncludeUnderscore)
1004 {
return (inIncludeUnderscore && inChar ==
'_') || IsUpperLetter(inChar) || IsLowerLetter(inChar);
1007 bool NTV2DeviceSpecParser::IsDecimalDigit (
const char inChar)
1008 {
static const string sDecDigits(
"0123456789");
1009 return sDecDigits.find(inChar) != string::npos;
1012 bool NTV2DeviceSpecParser::IsHexDigit (
const char inChar)
1013 {
static const string sHexDigits(
"0123456789ABCDEFabcdef");
1014 return sHexDigits.find(inChar) != string::npos;
1017 bool NTV2DeviceSpecParser::IsLegalSerialNumChar (
const char inChar)
1018 {
return IsLetter(inChar) || IsDecimalDigit(inChar);
1022 void NTV2DeviceSpecParser::test (
void)
1025 specParser.
Reset(
"1");
1026 specParser.
Reset(
"00000000000000000000000000000000000000000000000000000000000000000000000000000000000001");
1027 specParser.
Reset(
"corvid24");
1028 specParser.
Reset(
"corvid88");
1029 specParser.
Reset(
"konalhi");
1030 specParser.
Reset(
"alpha");
1031 specParser.
Reset(
"00T64450");
1032 specParser.
Reset(
"00t6-450");
1033 specParser.
Reset(
"BLATZBE0");
1034 specParser.
Reset(
"0x424C41545A424530");
1035 specParser.
Reset(
"0x424C415425424530");
1037 specParser.
Reset(
"badscheme://1");
1039 specParser.
Reset(
"ntv2local://1");
1040 specParser.
Reset(
"NtV2lOcAl://00000000000000000000000000000000000000000000000000000000000000000000000000000000000001");
1041 specParser.
Reset(
"NTV2Local://corvid24");
1042 specParser.
Reset(
"ntv2local://corvid88");
1043 specParser.
Reset(
"ntv2local://konalhi");
1044 specParser.
Reset(
"ntv2local://alpha");
1045 specParser.
Reset(
"ntv2local://00T64450");
1046 specParser.
Reset(
"ntv2local://00t6-450");
1047 specParser.
Reset(
"ntv2local://BLATZBE0");
1049 specParser.
Reset(
"ntv2nub://1.2.3.4");
1050 specParser.
Reset(
"ntv2nub://1.2.3.4/doc");
1051 specParser.
Reset(
"ntv2nub://1.2.3.4/doc/");
1052 specParser.
Reset(
"ntv2nub://1.2.3.4/doc/alpha?one&two=2&three=&four=4");
1053 specParser.
Reset(
"ntv2nub://1.2.3.4/doc/?one&two=2&three=&four=4");
1054 specParser.
Reset(
"ntv2nub://1.2.3.4:badport/doc?one&two=2&three=&four=4");
1055 specParser.
Reset(
"ntv2nub://1.2.3.4:200/doc?one&two=2&three=&four=4");
1056 specParser.
Reset(
"ntv2nub://1.2.3.4:200/doc/?one&two=2&three=&four=4");
1057 specParser.
Reset(
"ntv2nub://1.2.3.4:12345");
1058 specParser.
Reset(
"ntv2nub://1.2.3.4:65000/doc");
1059 specParser.
Reset(
"ntv2nub://1.2.3.4:32767/doc/");
1060 specParser.
Reset(
"ntv2nub://1.2.3.4/path/to/doc/");
1061 specParser.
Reset(
"ntv2nub://1.2.3.4/path/to/doc/?");
1062 specParser.
Reset(
"ntv2nub://1.2.3.4/path/to/doc?");
1063 specParser.
Reset(
"ntv2nub://1.2.3.4/path/to/doc/?one");
1064 specParser.
Reset(
"ntv2nub://1.2.3.4/path/to/doc?one");
1065 specParser.
Reset(
"ntv2nub://1.2.3.4/path/to/doc/?one=");
1066 specParser.
Reset(
"ntv2nub://1.2.3.4/path/to/doc?one=");
1067 specParser.
Reset(
"ntv2nub://1.2.3.4/path/to/doc/?one=1");
1068 specParser.
Reset(
"ntv2nub://1.2.3.4/path/to/doc?one=1");
1069 specParser.
Reset(
"ntv2nub://1.2.3.4/path/to/doc/?one=1&two");
1070 specParser.
Reset(
"ntv2nub://1.2.3.4/path/to/doc?one=1&two");
1071 specParser.
Reset(
"ntv2nub://50.200.250.300");
1072 specParser.
Reset(
"ntv2nub://fully.qualified.domain.name.com/path/to/doc/?one=1&two");
1073 specParser.
Reset(
"ntv2nub://fully.qualified.domain.name.edu:badport/path/to/doc/?one=1&two");
1074 specParser.
Reset(
"ntv2nub://fully.qualified.domain.name.info:5544/path/to/doc/?one=1&two");
1075 specParser.
Reset(
"ntv2nub://fully.qualified.domain.name.org/path/to/doc/?one=1&two");
1076 specParser.
Reset(
"ntv2nub://fully.qualified.domain.name.nz:badport/path/to/doc/?one=1&two");
1077 specParser.
Reset(
"ntv2nub://fully.qualified.domain.name.au:000004/path/to/doc/?one=1&two");
1078 specParser.
Reset(
"ntv2nub://fully.qualified.domain.name.ch:4/corvid88");
1079 specParser.
Reset(
"ntv2nub://fully.qualified.domain.name.cn:4/00T64450");
1080 specParser.
Reset(
"ntv2nub://fully.qualified.domain.name.ru:4/2");
1081 specParser.
Reset(
"ntv2nub://fully.qualified.domain.name.co.uk:4/00000000000000000000000000000001");
1082 specParser.
Reset(
"ntv2nub://fully.qualified.domain.name.com:4/0000000000000000000000000000000001");
1083 specParser.
Reset(
"ntv2://swdevice/?" 1085 "&supportlog=file%3A%2F%2F%2FUsers%2Fdemo%2FDesktop%2FAJAWatcherSupport.log" 1086 "&fbinit=file%3A%2F%2F%2FUsers%2Fdemo%2FDesktop%2FSDRAMsnapshot.dat");
1088 #endif // defined(_DEBUG) 1090 #if defined(MSWindows) 1091 static string WinErrStr (
const DWORD inErr)
1093 string result(
"foo");
1095 const DWORD res(FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER
1096 | FORMAT_MESSAGE_FROM_SYSTEM
1097 | FORMAT_MESSAGE_IGNORE_INSERTS,
1100 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1107 result =
reinterpret_cast<const char *
>(lpMsgBuf);
1108 LocalFree(lpMsgBuf);
1115 #if !defined(NTV2_PREVENT_PLUGIN_LOAD) 1128 static bool LoadPlugin (
const string & path,
const string & folderPath,
NTV2PluginPtr & outPtr,
string & outErrMsg,
const bool inUseStdout);
1131 #if defined(MSWindows) 1132 NTV2Plugin (HMODULE handle,
const string & path,
const bool useStdout);
1133 inline operator HMODULE()
const {
return mHandle;}
1135 NTV2Plugin (
void * handle,
const string & path,
const bool useStdout);
1136 inline operator void*()
const {
return mHandle;}
1139 inline bool isLoaded (
void)
const {
return mHandle && !mPath.empty() ?
true :
false;}
1140 void * addressForSymbol (
const string & inSymbol,
string & outErrorMsg);
1146 inline bool useStdout(
void) {
return mUseStdout;}
1148 #if defined(MSWindows) 1160 ostringstream loadErr;
1161 #if defined(AJABareMetal) 1163 #elif defined(MSWindows) 1165 std::wstring dllsFolderW;
1167 if (!AddDllDirectory(dllsFolderW.c_str()))
1169 loadErr <<
"AddDllDirectory '" << path <<
"' failed: " << WinErrStr(::GetLastError());
1172 HMODULE h = ::LoadLibraryExA(LPCSTR(path.c_str()),
AJA_NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
1175 const string errStr (::WinErrStr(::GetLastError()));
1176 if (!errStr.empty())
1179 if (!errStr.empty())
1180 cerr <<
"## ERROR: LoadPlugin failed to open '" << path <<
"':" << endl << errStr << endl;
1183 #else // MacOS or Linux 1185 void * h = ::dlopen(path.c_str(), RTLD_LAZY);
1188 const char * pErrorStr(::dlerror());
1189 const string errStr (pErrorStr ? pErrorStr :
"");
1190 if (!errStr.empty())
1193 if (!errStr.empty())
1194 cerr <<
"## ERROR: LoadPlugin failed to open '" << path <<
"':" << endl << loadErr.str() << endl;
1197 #endif // MacOS or Linux 1198 if (!loadErr.str().empty())
1199 outErrMsg = loadErr.str();
1202 outPtr =
new NTV2Plugin(h, path, inUseStdout);
1206 NTV2Plugin::NTV2Plugin()
1224 #if defined(MSWindows) 1235 P_NOTE(
"Dynamic/shared library '" << mPath <<
"' (" <<
INSTP(mHandle) <<
") loaded, " 1242 #if defined(AJABareMetal) 1244 #elif !defined(MSWindows) 1246 #else // macOS or Linux 1247 ::FreeLibrary(mHandle);
1250 P_NOTE(
"Dynamic/shared library '" << mPath <<
"' (" <<
INSTP(mHandle) <<
") unloaded, " 1258 outErrorMsg.clear();
1261 if (inSymbolName.empty())
1265 #if defined(AJABareMetal) 1267 #elif defined(MSWindows) 1268 result =
reinterpret_cast<void*
>(::GetProcAddress(reinterpret_cast<HMODULE>(mHandle), inSymbolName.c_str()));
1270 err <<
"'GetProcAddress' failed for '" << inSymbolName <<
"': " << WinErrStr(::GetLastError());
1271 #else // MacOS or Linux 1272 result = ::dlsym(mHandle, inSymbolName.c_str());
1274 {
const char * pErrorStr(::dlerror());
1275 const string errStr (pErrorStr ? pErrorStr :
"");
1276 err <<
"'dlsym' failed for '" << inSymbolName <<
"': " << errStr;
1278 #endif // MacOS or Linux 1279 outErrorMsg = err.str();
1298 static void Terminate (
void);
1299 static inline void EnableDebugging (
const bool inEnable =
true) {sDebugRegistry = inEnable;}
1305 bool loadPlugin (
const string & path,
const string & folderPath,
NTV2PluginPtr & outPtr,
string & errMsg,
const bool useStdout);
1306 bool unloadPlugin (
const string & path,
string & errMsg);
1307 bool pluginIsLoaded (
const string & path);
1308 bool pluginForPath (
const string & path,
NTV2PluginPtr & outHandle);
1311 bool hasPath (
const string & path);
1312 bool indexForPath (
const string & path,
size_t & outIndex);
1313 ULWord countForPath (
const string & path);
1314 uint32_t * refConForPath (
const string & path);
1315 inline bool useStdout (
void)
const {
return DebuggingEnabled();}
1318 typedef map<string, NTV2PluginPtr> NTV2PluginMap;
1322 NTV2PluginMap mPluginMap;
1327 static void Monitor (
AJAThread * pThread,
void * pContext);
1328 void monitor (
void);
1331 static bool sDebugRegistry;
1335 AJALock PluginRegistry::sMutex;
1336 bool PluginRegistry::sDebugRegistry(
false);
1353 void PluginRegistry::Monitor (
AJAThread * pThread,
void * pContext)
1355 PluginRegistry * pObj (reinterpret_cast<PluginRegistry*>(pContext));
1361 : mQuitMonitor(
false)
1363 P_NOTE (
"PluginRegistry " <<
INSTP(
this) <<
" constructed");
1364 mPluginCounts.reserve(256);
1365 for (
size_t num(0); num < 256; num++)
1366 mPluginCounts.push_back(0);
1367 mCompareCounts = mPluginCounts;
1368 mMonitor.
Attach(Monitor,
this);
1375 mQuitMonitor =
true;
1376 while (mMonitor.
Active())
1386 {
P_FAIL(
"empty path");
return false;}
1393 {
P_WARN(
INSTP(
this) <<
": '" << path <<
"': 'pluginForPath' returned false, but 'hasPath' returned true, count=" <<
countForPath(path));}
1396 {
P_FAIL(msg);
return false;}
1397 P_NOTE(
INSTP(
this) <<
": Dynamic/shared library '" << path <<
"' loaded");
1398 mPluginMap[path] = outPtr;
1399 mPluginPaths.push_back(path);
1400 mPluginCounts.at(mPluginPaths.size()-1) = 0;
1411 {
P_FAIL(
INSTP(
this) <<
": '" << path <<
"' requested to unload, but not loaded");
return false;}
1412 mPluginMap.erase(path);
1413 P_NOTE(
INSTP(
this) <<
": '" << path <<
"' unloaded");
1420 return mPluginMap.find(path) != mPluginMap.end();
1426 NTV2PluginMap::const_iterator it(mPluginMap.find(path));
1427 if (it == mPluginMap.end())
1430 outHandle = it->second;
1438 for (NTV2PluginMap::const_iterator it(mPluginMap.begin()); it != mPluginMap.end(); ++it)
1439 result.push_back(it->first);
1447 for (
size_t ndx(0); ndx < mPluginPaths.size(); ndx++)
1449 const string path (mPluginPaths.at(ndx));
1453 oss <<
"\t" << (p->
isLoaded() ?
"loaded" :
"unloaded");
1455 oss <<
"\t" <<
"---";
1456 result.push_back(oss.str());
1470 for (outIndex = 0; outIndex < mPluginPaths.size(); outIndex++)
1471 if (path == mPluginPaths.at(outIndex))
1481 return &mPluginCounts[ndx];
1489 return mPluginCounts.at(ndx);
1493 void PluginRegistry::monitor (
void)
1495 P_NOTE(
"PluginRegistry " <<
INSTP(
this) <<
" monitor started");
1496 ostringstream oss; oss <<
"PluginReg" <<
HEX0N(uint32_t(uint64_t(
this)),8);
1498 while (!mQuitMonitor)
1502 for (
size_t ndx(0); ndx < mPluginPaths.size(); ndx++)
1504 const uint32_t oldCount(mCompareCounts.at(ndx)), newCount(mPluginCounts.at(ndx));
1505 if (newCount != oldCount)
1507 string errMsg, path(mPluginPaths.at(ndx));
1508 if (newCount > oldCount)
1509 {
P_NOTE(
"PluginRegistry " <<
INSTP(
this) <<
": Plugin '" << path <<
"' utilization " 1510 <<
"increased from " <<
DEC(oldCount) <<
" to " <<
DEC(newCount));}
1513 P_NOTE(
"PluginRegistry " <<
INSTP(
this) <<
": Plugin '" << path <<
"' utilization " 1514 <<
"decreased from " <<
DEC(oldCount) <<
" to " <<
DEC(newCount));
1518 mCompareCounts.at(ndx) = newCount;
1524 P_NOTE(
"PluginRegistry " <<
INSTP(
this) <<
" monitor stopped");
1542 void *
refCon (
void)
const;
1546 void *
getSymbolAddress (
const string & inSymbolName,
string & outErrorMsg);
1560 mutable string errMsg;
1565 static string mbedErrStr (
const int mbedtlsReturnCode);
1593 { cout <<
"## NOTE: Original params for '" <<
pluginPath() <<
"':" << endl;
1594 originalParams.
Print(cout,
false) << endl;
1599 { cout <<
"## NOTE: Final params for '" <<
pluginPath() <<
"':" << endl;
1600 mDict.
Print(cout,
false) << endl;
1616 mbedtls_strerror (mbedtlsReturnCode, errBuff, errBuff);
1628 for (
size_t lineNdx(0); lineNdx < lines.size(); lineNdx++)
1630 string line (lines.at(lineNdx));
1631 const bool indented (line.empty() ?
false : line.at(0) ==
' ');
1636 if (keyValPair.size() != 2)
1638 if (keyValPair.size() == 1)
1640 keyPrefix = keyValPair.at(0);
1645 PLGFAIL(
"cert info line " <<
DEC(lineNdx+1) <<
" '" << line <<
"' has " 1646 <<
DEC(keyValPair.size()) <<
" column(s) -- expected 2");
1649 string key(keyValPair.at(0)), val(keyValPair.at(1));
1651 {
PLGFAIL(
"cert info line " <<
DEC(lineNdx+1) <<
" '" << line <<
"' empty key for value '" << val <<
"'");
continue;}
1652 if (indented && !keyPrefix.empty())
1653 {
aja::strip(key); key = keyPrefix +
": " + key;}
1671 for (
size_t ndx(0); ndx < pairs.size(); ndx++)
1673 string assignment (pairs.at(ndx));
1674 if (assignment.find(
'=') == string::npos)
1676 if (!lastKey.empty())
1682 if (pieces.size() != 2)
1683 {
PLGFAIL(
"'" << inParentKey <<
"' assignment '" << assignment <<
"' has " << pieces.size() <<
" component(s) -- expected 2");
continue;}
1684 lastKey = pieces.at(0);
1685 string val(pieces.at(1));
1694 outErrorMsg.clear();
1712 if (outPath.empty())
1714 PLGDBG(
"AJA plugin path is '" << outPath <<
"'");
1716 return !outPath.empty();
1726 {
P_FAIL(
"Missing scheme -- params: " << mDict);
return false;}
1730 return !outName.empty();
1751 const size_t maxBufSize = 512*1024*1024;
1754 dllF.open(
pluginPath(), std::ios::in | std::ios::binary);
1759 ifstream::pos_type curOffset(dllF.tellg());
1760 if (
int(curOffset) == -1)
1762 size_t size = size_t(curOffset);
1765 if (size > maxBufSize)
1766 {
P_FAIL(
"EOF not reached in plugin file '" <<
pluginPath() <<
"' -- over 500MB in size?");
return fail();}
1770 if (!dllF.seekg(0, ios_base::beg))
1771 {
P_FAIL(
"Could not seek back to start of plugin file '" <<
pluginPath() <<
"'");
return fail();}
1773 {
P_FAIL(
"EOF not reached in plugin file '" <<
pluginPath() <<
"' -- over 500MB in size?");
return fail();}
1774 tmp.
Truncate(
size_t(dllF.gcount()));
1778 ifstream sigF(
pluginSigPath().c_str(), std::ios::in | std::ios::binary);
1782 {
P_FAIL(
"EOF not reached in signature file '" <<
pluginSigPath() <<
"' -- over 500MB in size?");
return fail();}
1783 tmp.
Truncate(
size_t(sigF.gcount()));
1794 NTV2Buffer checksumFromSigFile, x509CertFromSigFile, signature;
1803 if (
isVerbose()) {
string s;
if (signature.toHexString(s)) cout <<
"## DEBUG1: signature: " << s << endl;}
1806 mbedtls_x509_crt crt;
1807 mbedtls_x509_crt_init(&crt);
1808 int ret = mbedtls_x509_crt_parse(&crt, x509CertFromSigFile, x509CertFromSigFile);
1811 mbedtls_x509_crt_free(&crt);
1819 int msgLength (mbedtls_x509_crt_info (msgBuff, msgBuff,
"", &crt));
1820 string msg (msgBuff,
size_t(msgLength));
1822 {
P_FAIL(
"'mbedtls_x509_crt_info' returned no info for X509 cert found in '" <<
pluginSigPath() <<
"'");
1823 mbedtls_x509_crt_free(&crt);
1827 cout <<
"## DEBUG: Raw X509 certificate info extracted from signature file '" <<
pluginSigPath() <<
"':" << endl
1828 <<
" " << msg << endl;
1830 { mbedtls_x509_crt_free(&crt);
1834 { cout <<
"## NOTE: X509 certificate info extracted from signature file '" <<
pluginSigPath() <<
"':" << endl;
1835 certInfo.
Print(cout,
false) << endl;
1837 if (certInfo.
hasKey(
"issuer name"))
1839 { mbedtls_x509_crt_free(&crt);
1842 if (certInfo.
hasKey(
"subject name"))
1844 { mbedtls_x509_crt_free(&crt);
1849 mbedtls_x509_crt_free(&crt);
1853 { cout <<
"## NOTE: 'issuer name' info:" << endl;
1854 issuerInfo.
Print(cout,
false) << endl;
1857 { cout <<
"## NOTE: 'subject name' info:" << endl;
1858 subjectInfo.
Print(cout,
false) << endl;
1862 mbedtls_x509_crt_free(&crt);
1867 mbedtls_x509_crt_free(&crt);
1872 mbedtls_x509_crt_free(&crt);
1880 ret = mbedtls_md_file (mbedtls_md_info_from_type(MBEDTLS_MD_SHA256),
pluginPath().c_str(), checksumFromDLL);
1883 mbedtls_x509_crt_free(&crt);
1886 if (
isVerbose()) {
string s;
if (checksumFromDLL.
toHexString(s)) cout <<
"## DEBUG: checksumFromDLL: " << s << endl;}
1887 if (
isVerbose()) {
string s;
if (signature.toHexString(s)) cout <<
"## DEBUG2: signature: " << s << endl;}
1890 ret = mbedtls_pk_verify (&crt.pk,
1898 mbedtls_x509_crt_free(&crt);
1901 mbedtls_x509_crt_free(&crt);
1902 P_DBG(
"'mbedtls_pk_verify' succeeded for '" <<
pluginPath() <<
"' -- signature valid");
1922 if (regInfo.
empty())
1931 for (
size_t ndx(0); ndx < reqKeys.size(); ndx++)
1932 if (!regInfo.
hasKey(reqKeys.at(ndx)))
1933 missingRegInfoKeys.push_back(reqKeys.at(ndx));
1934 if (!missingRegInfoKeys.empty())
1935 {
P_FAIL(
"'" <<
pluginPath() <<
"': missing key(s) in registration info: '" 1936 <<
aja::join(missingRegInfoKeys,
"','") <<
"'");
1953 if (onReg != onCert)
1956 <<
"') \"" << onCert <<
"\" from X509 certificate 'Issuer' in '" <<
pluginSigPath() <<
"'");
1959 if (cnReg != cnCert)
1962 <<
"') \"" << cnCert <<
"\" from X509 certificate 'Issuer' in '" <<
pluginSigPath() <<
"'");
1965 if (ouReg != ouCert)
1968 <<
"') \"" << ouCert <<
"\" from X509 certificate 'Subject' in '" <<
pluginSigPath() <<
"'");
1971 if (myVers != plVers)
1973 <<
"\" doesn't match client SDK version '" << myVers <<
"'");
1977 if (fingerprint != ajaFingerprint)
1979 <<
"Issuer serial: " << fingerprint <<
"|AJA serial: " << ajaFingerprint);
2008 return mpPlugin && mValidated;
2015 cout <<
"0 plugins" << endl;
2016 else if (paths.size() == 1)
2017 cout <<
"1 plugin: " << paths.at(0) << endl;
2018 else cout <<
DEC(paths.size()) <<
" plugins:" << endl <<
aja::join(paths,
"\n") << endl;
2020 #endif // !defined(NTV2_PREVENT_PLUGIN_LOAD) 2038 {cout << __FILE__ <<
"(" << __LINE__ <<
"):" <<
AJAFUNC <<
":" << endl;
mParams.
Print(cout,
false) << endl;}
2053 size_t oldCount(
mParams.
size()), updated(0), added(0);
2063 NBSDBG(
DEC(oldCount) <<
" param(s) removed, replaced with " << inNewParams);
2077 while (nums.size() > 3)
2085 static const string sAJAFingerprint (
"70:1A:37:93:FA:4F:34:30:58:55:51:0C:01:4E:45:7C:BE:5B:41:65");
2086 string result(sAJAFingerprint);
2140 oss << (
IsConnected() ?
"Connected" :
"Disconnected");
2142 oss <<
" to '" <<
Name() <<
"'";
2151 strs.push_back(
string(
"from '") + fName +
"'");
2154 if (!hostName.empty())
2155 {strs.push_back(
"on"); strs.push_back(
string(
"'") + hostName +
"'");}
2182 { (
void) autoCircData;
2187 { (
void) eInterrupt; (
void) timeOutMs;
2191 #if !defined(NTV2_DEPRECATE_16_3) 2193 { (
void) bitFileType;
2194 ::memset(&bitFileInfo, 0,
sizeof(bitFileInfo));
2200 ::memset(&buildInfo, 0,
sizeof(buildInfo));
2205 const UWord signalMask,
const bool testPatDMAEnb,
const ULWord testPatNum)
2206 { (
void) channel; (
void) testPatternFBF; (
void) signalMask; (
void) testPatDMAEnb; (
void) testPatNum;
2211 { (
void) numRegs; (
void) outFailedRegNum; (
void) outRegs;
2217 outDriverVersion = 0xFFFFFFFF;
2220 #endif // !defined(NTV2_DEPRECATE_16_3) 2224 const ULWord inNumSegments,
const ULWord inSegmentHostPitch,
2225 const ULWord inSegmentCardPitch,
const bool inSynchronous)
2226 { (
void) inDMAEngine; (
void) inIsRead; (
void) inFrameNumber; (
void) inOutFrameBuffer;
2227 (
void) inCardOffsetBytes; (
void) inNumSegments; (
void) inSegmentHostPitch;
2228 (
void) inSegmentCardPitch; (
void) inSynchronous;
2233 { (
void) pInMessage;
2251 outSupported.clear();
2269 #if defined(NTV2_PREVENT_PLUGIN_LOAD) 2282 }
catch (std::bad_alloc &) {
2283 pRPCObject =
nullptr;
2286 pRPCObject =
nullptr;
2305 #if defined(NTV2_PREVENT_PLUGIN_LOAD) 2318 }
catch (std::bad_alloc &) {
2319 pRPCObject =
nullptr;
2322 pRPCObject =
nullptr;
2337 if (parser.HasErrors())
2339 NBSFAIL(parser.Error() <<
" in URL:\n" << inURL);
2340 parser.PrintErrors(cerr);
static PluginRegistry & Get(void)
static bool ParseQueryParams(const NTV2Dictionary &inSrcDict, NTV2Dictionary &outQueryParams)
Parses the string found in the given source dictionary's 'query' key (kConnectParamQuery), storing the key/value pairs of all parsed query parameters into "outQueryParams". Query parameter values are URL-decoded before storing in the "outQueryParams" dictionary.
void * getFunctionAddress(const string &inFuncName)
bool useStdout(void) const
Everything needed to call CNTV2Card::ReadRegister or CNTV2Card::WriteRegister functions.
NTV2StringList loadedPlugins(void)
NTV2DeviceID DeviceID(void) const
#define kNTV2PluginRegInfoKey_LongName
Plugin long name.
#define kConnectParamDevSerial
Device with this serial number.
bool loadPlugin(const string &path, const string &folderPath, NTV2PluginPtr &outPtr, string &errMsg, const bool useStdout)
uint32_t gBaseConstructCount(0)
bool Allocate(const size_t inByteCount, const bool inPageAligned=false)
Allocates (or re-allocates) my user-space storage using the given byte count. I assume full responsib...
bool(* fpGetRegistrationInfo)(const uint32_t, NTV2Dictionary &)
Obtains a plugin's registration information. Starting in SDK 17.1, all plugins must implement this fu...
virtual bool ConnectHasScheme(void) const
virtual AJAStatus SetThreadName(const char *name)
virtual bool NTV2ReadRegisterMultiRemote(const ULWord numRegs, ULWord &outFailedRegNum, NTV2RegInfo outRegs[])
uint32_t gClientConstructCount(0)
virtual bool NTV2GetNumericParamRemote(const ULWord inParamID, ULWord &outValue)
unsigned long long stoull(const std::string &str, std::size_t *idx, int base)
void DumpLoadedPlugins(void)
NTV2DeviceIDSet NTV2GetSupportedDevices(const NTV2DeviceKinds inKinds=NTV2_DEVICEKIND_ALL)
Returns an NTV2DeviceIDSet of devices supported by the SDK.
virtual bool NTV2Connect(void)
NTV2FrameBufferFormat
Identifies a particular video frame buffer pixel format. See Device Frame Buffer Formats for details...
#define kConnectParamPort
Port number (optional)
NTV2RPCClientAPI *(* fpCreateClient)(void *, const NTV2ConnectParams &, const uint32_t)
Instantiates a new client instance to talk to a remote server.
NTV2StringSet::const_iterator NTV2StringSetConstIter
Declares the AJADebug class.
std::string valueForKey(const std::string &inKey) const
uint16_t u16ValueForKey(const std::string &inKey, const uint16_t inDefault=0) const
#define kQParamShowX509Cert
Query parameter option that dumps X509 certificate info into message log.
bool pluginForPath(const string &path, NTV2PluginPtr &outHandle)
static AJAStatus Open(bool incrementRefCount=false)
#define kNTV2PluginRegInfoKey_Copyright
Plugin copyright notice.
bool showParams(void) const
#define kNTV2PluginRegInfoKey_Vendor
Plugin vendor (manufacturer) name.
#define kQParamVerboseLogging
Query parameter option that enables verbose message logging.
NTV2StringList::const_iterator NTV2StringListConstIter
NTV2Plugin(void *handle, const string &path, const bool useStdout)
#define kNTV2PluginX500AttrKey_OrganizationName
static int32_t Decrement(int32_t volatile *pTarget)
the parser read a key of a value in an object
static string mbedErrStr(const int mbedtlsReturnCode)
#define kLegalSchemeNTV2Local
ULWord GetByteCount(void) const
#define kNTV2PluginRegInfoKey_ShortName
Plugin short name.
bool pluginIsLoaded(const string &path)
One-stop shop for parsing device specifications. (New in SDK 16.3) I do very little in the way of val...
Declares the AJATime class.
virtual AJAStatus SetPriority(AJAThreadPriority priority)
uint32_t gLoaderConstructCount(0)
virtual bool NTV2GetSupportedRemote(const ULWord inEnumsID, ULWordSet &outSupported)
size_t erase(const std::string &inKey)
Erases the given key and its corresponding value from me, returns 1 if successful, 0 if not.
bool string_to_wstring(const std::string &str, std::wstring &wstr)
virtual bool HasConnectParam(const std::string &inParam) const
static bool ExtractCertInfo(NTV2Dictionary &outInfo, const string &inStr)
UWord DeviceIndex(void) const
virtual std::string ConnectParam(const std::string &inParam) const
Dict::const_iterator DictConstIter
Common base class for NTV2RPCClientAPI and NTV2RPCServerAPI.
Defines the AJARefPtr template class.
bool showCertificate(void) const
virtual AJAStatus Start()
NTV2RPCServerAPI(NTV2ConnectParams inParams, void *pRefCon)
My constructor.
bool hasPath(const string &path)
bool serialize(std::string &outStr) const
Serializes my contents into the given string, returns true if string is not empty.
#define kQParamDebugRegistry
Query parameter option that enables debugging of PluginRegistry.
NTV2Channel
These enum values are mostly used to identify a specific widget_framestore. They're also commonly use...
std::ostream & Print(std::ostream &oss, const bool inDumpResults=false) const
bool toHexString(std::string &outStr, const size_t inLineBreakInterval=0) const
Converts my contents into a hex-encoded string.
Declares NTV2 "nub" client functions.
std::string MakeDeviceSpec(const bool urlEncodeQuery) const
bool hasKey(const std::string &inKey) const
#define kConnectParamDevModel
First device of this model (e.g. 'kona4')
static bool ExtractIssuerInfo(NTV2Dictionary &outInfo, const string &inStr, const string &inParentKey)
AJALock mParamLock
Mutex to protect mParams.
virtual std::string Name(void) const
NTV2Dictionary mParams
Copy of config params passed to my constructor.
#define NTV2_ASSERT(_expr_)
virtual bool NTV2DMATransferRemote(const NTV2DMAEngine inDMAEngine, const bool inIsRead, const ULWord inFrameNumber, NTV2Buffer &inOutBuffer, const ULWord inCardOffsetBytes, const ULWord inNumSegments, const ULWord inSegmentHostPitch, const ULWord inSegmentCardPitch, const bool inSynchronous)
#define kConnectParamDevID
First device having this ID (e.g. '0x10518400')
#define kConnectParamHost
DNS name, IPv4 or sw device DLL name.
uint32_t gPluginConstructCount(0)
bool Truncate(const size_t inByteCount)
Truncates me to the given length. No reallocation takes place.
#define kNTV2PluginSigFileKey_X509Certificate
X509 certificate (encoded as hex string)
unsigned long stoul(const std::string &str, std::size_t *idx, int base)
NTV2RPCServerAPI *(* fpCreateServer)(void *, const NTV2ConfigParams &, const uint32_t)
Instantiates a new server instance for talking to clients.
virtual bool NTV2GetBoolParamRemote(const ULWord inParamID, ULWord &outValue)
virtual std::ostream & Print(std::ostream &oss) const
void * addressForSymbol(const string &inSymbol, string &outErrorMsg)
bool Fill(const T &inValue)
Fills me with the given scalar value.
std::string PercentEncode(const std::string &inStr)
bool GetString(std::string &outString, const size_t inU8Offset=0, const size_t inMaxSize=128) const
Answers with my contents as a character string.
static std::string AJAFingerprint(const bool inLowerCase=false, const bool inStripColons=false)
An object that can connect to, and operate remote or fake devices. I have three general API groups: ...
NTV2StringSet keys(void) const
#define kFuncNameCreateServer
Create an NTV2RPCServerAPI instance.
std::string NTV2Version(const bool inDetailed=false)
bool insert(const std::string &inKey, const std::string &inValue)
Stores the given value using the given key; overwrites existing value if already present.
#define kNTV2PluginInfoKey_Fingerprint
Issuer cert fingerprint.
NTV2PluginLoader(NTV2Dictionary ¶ms)
NTV2DeviceID
Identifies a specific AJA NTV2 device model number. The NTV2DeviceID is actually the PROM part number...
static void EnableDebugging(const bool inEnable=true)
virtual bool NTV2Disconnect(void)
Disconnects me from the remote/fake host, closing the connection.
Declares the AJAThread class.
virtual void RunServer(void)
Principal server thread function, subclsses should override.
bool SetParams(const NTV2ConfigParams &inNewParams, const bool inAugment=false)
virtual void Stop(void)
Call this to request the server to stop.
virtual ~NTV2RPCClientAPI()
My destructor, automatically calls NTV2Disconnect.
virtual bool NTV2DriverGetBitFileInformationRemote(BITFILE_INFO_STRUCT &nfo, const NTV2BitFileType typ)
void Reset(const std::string inSpec="")
Resets me, then parses the given device specification.
virtual std::ostream & Print(std::ostream &oss) const
NTV2DeviceIDSet::const_iterator NTV2DeviceIDSetConstIter
A convenient const iterator for NTV2DeviceIDSet.
bool indexForPath(const string &path, size_t &outIndex)
std::set< std::string > NTV2StringSet
size_t addFrom(const NTV2Dictionary &inDict)
Adds all values from inDict with non-matching keys, ignoring all matching keys.
uint32_t gServerDestructCount(0)
uint32_t gClientDestructCount(0)
virtual bool NTV2MessageRemote(NTV2_HEADER *pInMessage)
size_t largestKeySize(void) const
std::string HostWithPort(void) const
bool isLoaded(void) const
#define kNTV2PluginInfoKey_Errors
Plugin load or validation error(s), if any.
Declares the most fundamental data types used by NTV2. Since Windows NT was the first principal devel...
void clear(void)
Removes all of my key/value pairs.
Defines for the NTV2 SDK version number, used by ajantv2/includes/ntv2enums.h. See the ajantv2/includ...
enum _INTERRUPT_ENUMS_ INTERRUPT_ENUMS
static void Sleep(const int32_t inMilliseconds)
Suspends execution of the current thread for a given number of milliseconds.
virtual bool NTV2CloseRemote(void)
std::ostream & Print(std::ostream &oss, const bool inCompact=true) const
Prints human-readable representation to ostream.
void split(const std::string &str, const char delim, std::vector< std::string > &elems)
#define kNTV2PluginX500AttrKey_OrganizationalUnitName
bool isVerbose(void) const
std::set< ULWord > ULWordSet
A collection of unique ULWord (uint32_t) values.
bool getBaseNameFromScheme(string &outName) const
#define kNTV2PluginRegInfoKey_Description
Brief plugin description.
All new NTV2 structs start with this common header.
virtual bool IsConnected(void) const
the parser finished reading a JSON value
NTV2RPCClientAPI(NTV2ConnectParams inParams, void *pRefCon)
My constructor.
static bool DebuggingEnabled(void)
bool useStdout(void) const
#define kQParamVDevFileName
.vdev file name (with extension)
static int32_t Increment(int32_t volatile *pTarget)
std::string Resource(const bool inStripLeadSlash=true) const
virtual bool NTV2WaitForInterruptRemote(const INTERRUPT_ENUMS eInterrupt, const ULWord timeOutMs)
std::string NTV2GetPluginsFolderPath(const bool inAddTrailingPathDelim=false)
uint32_t * refConForPath(const string &path)
uint32_t mSpare[1024]
Reserved.
static NTV2RPCClientAPI * CreateClient(NTV2ConnectParams &inParams)
Instantiates a new NTV2RPCClientAPI instance using the given NTV2ConnectParams.
#define kNTV2PluginRegInfoKey_CommonName
Plugin vendor domain name.
Base class of objects that can serve device operation RPCs with NTV2RPCClientAPI instances.
#define kNTV2PluginInfoKey_PluginPath
Local host full path to plugin file.
virtual bool IsRunning(void) const
virtual NTV2ConfigParams ConfigParams(void) const
static void Terminate(void)
virtual bool NTV2ReadRegisterRemote(const ULWord regNum, ULWord &outRegValue, const ULWord regMask, const ULWord regShift)
#define kQParamLogToStdout
Query parameter option that logs messages to standard output.
ULWord countForPath(const string &path)
void * refCon(void) const
bool mTerminate
Set true to stop server.
Describes a user-space buffer on the host computer. I have an address and a length, plus some optional attributes (allocated by SDK?, page-aligned? etc.).
bool deserialize(const std::string &inStr)
Resets me from the given string.
#define AJA_sERROR(_index_, _expr_)
std::string MakeQueryString(const bool urlEncode) const
bool getPluginsFolder(string &outPath) const
string pluginSigPath(void) const
#define kNTV2PluginInfoKey_PluginBaseName
Plugin base name (i.e. without extension)
std::string NTV2DeviceIDToString(const NTV2DeviceID inValue, const bool inForRetailDisplay=false)
#define kFuncNameGetRegInfo
Answers with plugin registration info.
virtual bool NTV2DriverGetBuildInformationRemote(BUILD_INFO_STRUCT &buildInfo)
Declares the AJAAtomic class.
std::string & strip(std::string &str, const std::string &ws)
#define kConnectParamDevIndex
Device having this index number.
#define kNTV2PluginInfoKey_PluginsPath
Local host full path to folder containing plugins.
#define kQParamShowParams
Query parameter option that dumps parameters into message log.
virtual std::string Description(void) const
bool unloadPlugin(const string &path, string &errMsg)
std::string PercentDecode(const std::string &inStr)
bool isValidated(void) const
virtual bool NTV2OpenRemote(void)
NTV2RPCBase(NTV2Dictionary params, uint32_t *pRefCon)
#define kNTV2PluginX500AttrKey_CommonName
std::ostream & PrintErrors(std::ostream &oss) const
AJARefPtr< NTV2Plugin > NTV2PluginPtr
#define kNTV2PluginRegInfoKey_OrgUnit
Plugin organization unit (to match certificate subject OU)
static bool LoadPlugin(const string &path, const string &folderPath, NTV2PluginPtr &outPtr, string &outErrMsg, const bool inUseStdout)
Declares numerous NTV2 utility functions.
virtual ~NTV2RPCServerAPI()
My destructor, automatically calls NTV2Disconnect.
uint32_t * mpRefCon
Reserved for internal use.
virtual AJAStatus Attach(AJAThreadFunction *pThreadFunction, void *pUserContext)
virtual bool NTV2GetDriverVersionRemote(ULWord &vers)
Declares the AJASystemInfo class.
size_t updateFrom(const NTV2Dictionary &inDict)
Updates all values from inDict with matching keys, ignoring all non-matching keys.
uint32_t gLoaderDestructCount(0)
#define kConnectParamScheme
URL scheme.
virtual bool HasConfigParam(const std::string &inParam) const
AJARefPtr< PluginRegistry > PluginRegistryPtr
#define AJA_NTV2_SDK_VERSION
size_t largestValueSize(void) const
#define kNTV2PluginRegInfoKey_Version
Plugin version (string)
NTV2DeviceSpecParser(const std::string inSpec="")
My constructor. If given device specification is non-empty, proceeds to Parse it. ...
#define xHEX0N(__x__, __n__)
A simple (not thread-safe) set of key/value pairs. (New in SDK 16.3)
virtual bool NTV2WriteRegisterRemote(const ULWord regNum, const ULWord regValue, const ULWord regMask, const ULWord regShift)
Private include file for all ajabase sources.
std::vector< uint32_t > ULWordSequence
An ordered sequence of ULWord (uint32_t) values.
#define kNTV2PluginSigFileKey_Signature
X509 digital signature (encoded as hex string)
std::string & upper(std::string &str)
#define kNTV2PluginRegInfoKey_NTV2SDKVersion
NTV2 SDK version that plugin was compiled with.
virtual AJAStatus GetValue(const AJASystemInfoTag inTag, std::string &outValue) const
Answers with the host system info value string for the given AJASystemInfoTag.
#define kFuncNameCreateClient
Create an NTV2RPCClientAPI instance.
std::string join(const std::vector< std::string > &parts, const std::string &delim)
std::set< NTV2DeviceID > NTV2DeviceIDSet
A set of NTV2DeviceIDs.
void * GetHostPointer(void) const
string pluginsPath(void) const
uint32_t gBaseDestructCount(0)
void * getSymbolAddress(const string &inSymbolName, string &outErrorMsg)
std::vector< std::string > NTV2StringList
#define HEX0N(__x__, __n__)
uint32_t gPluginDestructCount(0)
string pluginPath(void) const
std::string & lower(std::string &str)
virtual NTV2ConnectParams ConnectParams(void) const
std::string InfoString(void) const
static NTV2RPCServerAPI * CreateServer(NTV2ConfigParams &inParams)
Factory method that instantiates a new NTV2RPCServerAPI instance using a plugin based on the specifie...
Declares enums and structs used by all platform drivers and the SDK.
virtual bool NTV2AutoCirculateRemote(AUTOCIRCULATE_DATA &autoCircData)
#define kConnectParamQuery
Query – everything past '?' in URL.
virtual std::string ConfigParam(const std::string &inParam) const
std::string & replace(std::string &str, const std::string &from, const std::string &to)
static std::string ShortSDKVersion(void)
uint32_t gServerConstructCount(0)
#define kConnectParamResource
Resource path – everything past URL [scheme://host[:port]/], excluding [?query]. ...
#define AJA_sDEBUG(_index_, _expr_)
NTV2StringList pluginStats(void)
virtual bool NTV2DownloadTestPatternRemote(const NTV2Channel ch, const NTV2PixelFormat pf, const UWord msk, const bool dma, const ULWord tpNum)
string pluginBaseName(void) const
#define kNTV2PluginInfoKey_PluginSigPath
Local host full path to plugin signature file.