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 (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) ==
'/')
309 void NTV2DeviceSpecParser::Parse (
void)
318 string tokDevID, tokIndexNum, tokScheme, tokSerial, tokModelName, tokIPV4, tokPortNum;
319 size_t posDevID(0), posIndexNum(0), posScheme(0), posSerial(0), posModelName(0), posNetAddr(0);
320 bool isSerial(ParseSerialNum(posSerial, tokSerial)), isScheme(ParseScheme(posScheme, tokScheme));
321 bool isIndexNum(ParseDecNumber(posIndexNum, tokIndexNum)), isDeviceID(ParseDeviceID(posDevID, tokDevID));
322 bool isModelName(ParseModelName(posModelName, tokModelName));
323 bool isIPV4Port(ParseHostAddressAndPortNumber(posNetAddr, tokIPV4, tokPortNum));
326 posDevID = posIndexNum = posSerial = posModelName = posScheme;
327 isSerial = ParseSerialNum(posSerial, tokSerial);
328 isIndexNum = ParseDecNumber(posIndexNum, tokIndexNum);
329 isDeviceID = ParseDeviceID(posDevID, tokDevID);
330 isModelName = ParseModelName(posModelName, tokModelName);
333 if (isDeviceID) posQuery = posDevID;
334 else if (isSerial) posQuery = posSerial;
335 else if (isModelName) posQuery = posModelName;
336 else if (isIndexNum) posQuery = posIndexNum;
340 if (ParseQuery(posQuery, params))
343 mQueryParams = params;
345 if (isDeviceID) posDevID = mPos;
346 else if (isSerial) posSerial = mPos;
347 else if (isModelName) posModelName = mPos;
348 else if (isIndexNum) posIndexNum = mPos;
363 bool converted(
false);
365 if (tokSerial.length() == 18)
368 const bool hasLeading0X (tokSerial.find(
"0X") == 0 || tokSerial.find(
"0x") == 0);
369 const string hex64(tokSerial.substr(hasLeading0X ? 2 : 0, 16));
372 for (
size_t ndx(0); ndx < 8; ndx++)
373 serTxt +=
char(serNum64 >> ((7-ndx)*8));
379 for (
size_t ndx(0); ndx < tokSerial.length(); ndx++)
380 {
char ch(tokSerial.at(ndx));
381 if ( ! ( ( (ch >=
'0') && (ch <=
'9') ) ||
382 ( (ch >=
'A') && (ch <=
'Z') ) ||
383 ( (ch >=
'a') && (ch <=
'z') ) ||
384 (ch ==
' ') || (ch ==
'-') ) )
386 err <<
"Illegal serial number character '" << (ch ? ch :
'?') <<
"' (" <<
xHEX0N(
UWord(ch),2) <<
")";
388 mPos -= converted ? 16 : 8; mPos += ndx * (converted ? 2 : 1) + (converted ? 1 : 0);
405 if (posIndexNum < SpecLength())
407 if (isIPV4Port && !tokIPV4.empty())
412 if (!tokPortNum.empty())
416 err <<
"Extra characters past index number";
427 err <<
"Invalid local device specification";
429 mPos += isScheme ? 12 : 0;
440 size_t posURL(posScheme), posRsrc(0);
441 string host, port, rsrcPath;
442 if (!ParseHostAddressAndPortNumber(posURL, host, port))
443 {mPos = posURL; AddError(
"Bad host address or port number");
break;}
452 if (ParseResourcePath(posRsrc, rsrcPath))
455 size_t posQuery(mPos);
457 if (ParseQuery(posQuery, params))
460 mQueryParams = params;
465 if (mPos < SpecLength())
466 {err <<
"Parser failed at character position " <<
DEC(mPos); AddError(err.str());}
470 { oss <<
"NTV2DeviceSpecParser::Parse success: '" << DeviceSpec() <<
"' -- ";
475 { oss <<
"NTV2DeviceSpecParser::Parse failed: ";
479 #endif // defined(_DEBUG) 485 oss <<
"local device";
486 else if (HasScheme())
487 oss <<
"device '" << Scheme() <<
"'";
491 oss <<
" serial '" << DeviceSerial() <<
"'";
493 oss <<
" model '" << DeviceModel() <<
"'";
495 oss <<
" ID '" << DeviceID() <<
"'";
497 oss <<
" " << DeviceIndex();
507 {oss << endl; Results().Print(oss,
false);}
515 ostringstream result;
518 result <<
"ntv2local://";
520 result << DeviceSerial();
522 result << DeviceModel();
524 result << DeviceID();
526 result << DeviceIndex();
531 result << Scheme() <<
"://";
537 if (HasQueryParams())
539 string q (MakeQueryString(urlEncodeQuery));
550 if (!HasQueryParams())
557 string k(*it), v(mQueryParams.valueForKey(k));
561 oss << k <<
"=" << v;
562 parms.push_back(oss.str());
577 if (devIDStr.find(
"0X") != string::npos)
592 oss <<
DEC(ErrorCount()) << (ErrorCount() == 1 ?
" error" :
" errors") << (HasErrors() ?
":" :
"");
596 << DeviceSpec() << endl
597 << string(mPos ? mPos : 0,
' ') <<
"^" << endl;
598 for (
size_t num(0); num < ErrorCount(); )
601 if (++num < ErrorCount())
608 bool NTV2DeviceSpecParser::ParseHexNumber (
size_t & pos,
string & outToken)
612 while (pos < SpecLength())
614 const char ch(CharAt(pos));
615 if (tokHexNum.length() == 0)
619 ++pos; tokHexNum = ch;
621 else if (tokHexNum.length() == 1)
623 if (ch !=
'x' && ch !=
'X')
625 ++pos; tokHexNum += ch;
631 ++pos; tokHexNum += ch;
634 if (tokHexNum.length() > 2)
635 {
aja::upper(tokHexNum); outToken = tokHexNum;}
636 return !outToken.empty();
639 bool NTV2DeviceSpecParser::ParseDecNumber (
size_t & pos,
string & outToken)
643 while (pos < SpecLength())
645 const char ch(CharAt(pos));
646 if (!IsDecimalDigit(ch))
649 if (ch !=
'0' || tokDecNum !=
"0")
652 if (tokDecNum.length() > 0)
653 outToken = tokDecNum;
654 return !outToken.empty();
657 bool NTV2DeviceSpecParser::ParseAlphaNum (
size_t & pos,
string & outToken,
const std::string & inOtherChars)
661 while (pos < SpecLength())
663 const char ch(CharAt(pos));
664 if (!IsLetter(ch) && !IsDecimalDigit(ch) && inOtherChars.find(ch) == string::npos)
666 if (tokAlphaNum.empty() && !IsLetter(ch))
668 ++pos; tokAlphaNum += ch;
670 if (tokAlphaNum.length() > 0)
671 outToken = tokAlphaNum;
672 return !outToken.empty();
675 bool NTV2DeviceSpecParser::ParseAlphaNumeric (
size_t & pos,
string & outToken,
const std::string & inOtherChars)
679 while (pos < SpecLength())
681 const char ch(CharAt(pos));
682 if (!IsLetter(ch) && !IsDecimalDigit(ch) && inOtherChars.find(ch) == string::npos)
684 ++pos; tokAlphaNum += ch;
686 if (tokAlphaNum.length() > 0)
687 outToken = tokAlphaNum;
688 return !outToken.empty();
691 bool NTV2DeviceSpecParser::ParseScheme (
size_t & pos,
string & outToken)
694 string rawScheme, tokScheme;
695 while (ParseAlphaNum(pos, rawScheme))
697 tokScheme = rawScheme;
698 char ch(CharAt(pos));
701 ++pos; tokScheme += ch;
706 ++pos; tokScheme += ch;
711 ++pos; tokScheme += ch;
714 if (tokScheme.find(
"://") != string::npos)
715 {
aja::lower(rawScheme); outToken = rawScheme;}
716 return !outToken.empty();
719 bool NTV2DeviceSpecParser::ParseSerialNum (
size_t & pos,
string & outToken)
722 string tokAlphaNum, tokHexNum;
723 size_t origPos(pos), posAlphaNum(pos), posHexNum(pos);
726 while (posAlphaNum < SpecLength())
728 const char ch(CharAt(posAlphaNum));
729 if (!IsUpperLetter(ch) && !IsLowerLetter(ch) && !IsDecimalDigit(ch) && ch !=
'-' && ch !=
' ')
731 ++posAlphaNum; tokAlphaNum += ch;
733 if (tokAlphaNum.length() < 2)
734 {tokAlphaNum.clear();
break;}
735 if (tokAlphaNum.length() == 8 || tokAlphaNum.length() == 9)
736 {pos = posAlphaNum; outToken = tokAlphaNum;
break;}
738 if (ParseHexNumber(posHexNum, tokHexNum))
739 if (tokHexNum.length() == 18)
740 {pos = posHexNum; outToken = tokHexNum;}
742 if (tokAlphaNum ==
"ntv2kona1")
743 {outToken.clear(); pos = origPos;
return false;}
744 return !outToken.empty();
747 bool NTV2DeviceSpecParser::ParseDeviceID (
size_t & pos,
string & outToken)
751 if (!ParseHexNumber(pos, tokHexNum))
753 if (tokHexNum.length() != 10)
762 ostringstream devID; devID <<
xHEX0N(*it,8);
763 string devIDStr(devID.str());
765 devIDStrs.insert(devIDStr);
767 if (devIDStrs.find(tokHexNum) != devIDStrs.end())
768 outToken = tokHexNum;
769 return !outToken.empty();
772 bool NTV2DeviceSpecParser::ParseModelName (
size_t & pos,
string & outToken)
776 if (!ParseAlphaNum(pos, tokName,
" "))
787 modelNames.insert(modelName);
789 if (modelNames.find(tokName) != modelNames.end())
791 return !outToken.empty();
794 bool NTV2DeviceSpecParser::ParseDNSName (
size_t & pos,
string & outDNSName)
797 string dnsName, name;
800 while (ParseAlphaNum(dnsPos, name,
"_-"))
802 if (!dnsName.empty())
810 if (!dnsName.empty())
812 outDNSName = dnsName;
813 return !outDNSName.empty();
816 bool NTV2DeviceSpecParser::ParseIPv4Address (
size_t & pos,
string & outIPv4)
823 while (ParseDecNumber(ipv4Pos, num))
825 ipv4Name.push_back(num);
826 ch = CharAt(ipv4Pos);
831 if (ipv4Name.size() == 4)
834 return ipv4Name.size() == 4;
837 bool NTV2DeviceSpecParser::ParseHostAddressAndPortNumber (
size_t & pos,
string & outAddr,
string & outPort)
839 outAddr.clear(); outPort.clear();
841 string dnsName, ipv4, port;
842 size_t dnsPos(pos), ipv4Pos(pos), portPos(0);
843 bool isDNS(ParseDNSName(dnsPos, dnsName)), isIPv4(ParseIPv4Address(ipv4Pos, ipv4));
844 if (!isDNS && !isIPv4)
845 {pos = dnsPos < ipv4Pos ? ipv4Pos : dnsPos;
return false;}
848 {outAddr = ipv4; pos = portPos = ipv4Pos;}
850 {outAddr = dnsName; pos = portPos = dnsPos;}
853 char ch (CharAt(portPos));
857 if (!ParseDecNumber(portPos, port))
858 {pos = portPos;
return false;}
864 bool NTV2DeviceSpecParser::ParseResourcePath (
size_t & pos,
string & outRsrc)
869 char ch(CharAt(rsrcPos));
874 if (!ParseAlphaNumeric(rsrcPos, name,
" "))
877 ch = CharAt(rsrcPos);
882 return !outRsrc.empty();
885 bool NTV2DeviceSpecParser::ParseParamAssignment (
size_t & pos,
string & outKey,
string & outValue)
887 outKey.clear(); outValue.clear();
889 size_t paramPos(pos);
890 char ch(CharAt(paramPos));
892 ch = CharAt(++paramPos);
895 if (!ParseAlphaNumeric(paramPos, key))
897 ch = CharAt(paramPos);
900 ch = CharAt(++paramPos);
901 while (ch != 0 && ch !=
'&')
904 ch = CharAt(++paramPos);
908 {pos = paramPos; outKey =
key; outValue =
value;}
912 bool NTV2DeviceSpecParser::ParseQuery (
size_t & pos,
NTV2Dictionary & outParams)
916 size_t queryPos(pos);
917 char ch(CharAt(queryPos));
922 while (ParseParamAssignment(queryPos, key, value))
924 outParams.
insert(key, value);
925 ch = CharAt(queryPos);
929 if (!outParams.
empty())
931 return !outParams.
empty();
934 bool NTV2DeviceSpecParser::IsUpperLetter (
const char inChar)
935 {
static const string sHexDigits(
"_ABCDEFGHIJKLMNOPQRSTUVWXYZ");
936 return sHexDigits.find(inChar) != string::npos;
939 bool NTV2DeviceSpecParser::IsLowerLetter (
const char inChar)
940 {
static const string sHexDigits(
"abcdefghijklmnopqrstuvwxyz");
941 return sHexDigits.find(inChar) != string::npos;
944 bool NTV2DeviceSpecParser::IsLetter (
const char inChar,
const bool inIncludeUnderscore)
945 {
return (inIncludeUnderscore && inChar ==
'_') || IsUpperLetter(inChar) || IsLowerLetter(inChar);
948 bool NTV2DeviceSpecParser::IsDecimalDigit (
const char inChar)
949 {
static const string sDecDigits(
"0123456789");
950 return sDecDigits.find(inChar) != string::npos;
953 bool NTV2DeviceSpecParser::IsHexDigit (
const char inChar)
954 {
static const string sHexDigits(
"0123456789ABCDEFabcdef");
955 return sHexDigits.find(inChar) != string::npos;
958 bool NTV2DeviceSpecParser::IsLegalSerialNumChar (
const char inChar)
959 {
return IsLetter(inChar) || IsDecimalDigit(inChar);
963 void NTV2DeviceSpecParser::test (
void)
966 specParser.
Reset(
"1");
967 specParser.
Reset(
"00000000000000000000000000000000000000000000000000000000000000000000000000000000000001");
968 specParser.
Reset(
"corvid24");
969 specParser.
Reset(
"corvid88");
970 specParser.
Reset(
"konalhi");
971 specParser.
Reset(
"alpha");
972 specParser.
Reset(
"00T64450");
973 specParser.
Reset(
"00t6-450");
974 specParser.
Reset(
"BLATZBE0");
975 specParser.
Reset(
"0x424C41545A424530");
976 specParser.
Reset(
"0x424C415425424530");
978 specParser.
Reset(
"badscheme://1");
980 specParser.
Reset(
"ntv2local://1");
981 specParser.
Reset(
"NtV2lOcAl://00000000000000000000000000000000000000000000000000000000000000000000000000000000000001");
982 specParser.
Reset(
"NTV2Local://corvid24");
983 specParser.
Reset(
"ntv2local://corvid88");
984 specParser.
Reset(
"ntv2local://konalhi");
985 specParser.
Reset(
"ntv2local://alpha");
986 specParser.
Reset(
"ntv2local://00T64450");
987 specParser.
Reset(
"ntv2local://00t6-450");
988 specParser.
Reset(
"ntv2local://BLATZBE0");
990 specParser.
Reset(
"ntv2nub://1.2.3.4");
991 specParser.
Reset(
"ntv2nub://1.2.3.4/doc");
992 specParser.
Reset(
"ntv2nub://1.2.3.4/doc/");
993 specParser.
Reset(
"ntv2nub://1.2.3.4/doc/alpha?one&two=2&three=&four=4");
994 specParser.
Reset(
"ntv2nub://1.2.3.4/doc/?one&two=2&three=&four=4");
995 specParser.
Reset(
"ntv2nub://1.2.3.4:badport/doc?one&two=2&three=&four=4");
996 specParser.
Reset(
"ntv2nub://1.2.3.4:200/doc?one&two=2&three=&four=4");
997 specParser.
Reset(
"ntv2nub://1.2.3.4:200/doc/?one&two=2&three=&four=4");
998 specParser.
Reset(
"ntv2nub://1.2.3.4:12345");
999 specParser.
Reset(
"ntv2nub://1.2.3.4:65000/doc");
1000 specParser.
Reset(
"ntv2nub://1.2.3.4:32767/doc/");
1001 specParser.
Reset(
"ntv2nub://1.2.3.4/path/to/doc/");
1002 specParser.
Reset(
"ntv2nub://1.2.3.4/path/to/doc/?");
1003 specParser.
Reset(
"ntv2nub://1.2.3.4/path/to/doc?");
1004 specParser.
Reset(
"ntv2nub://1.2.3.4/path/to/doc/?one");
1005 specParser.
Reset(
"ntv2nub://1.2.3.4/path/to/doc?one");
1006 specParser.
Reset(
"ntv2nub://1.2.3.4/path/to/doc/?one=");
1007 specParser.
Reset(
"ntv2nub://1.2.3.4/path/to/doc?one=");
1008 specParser.
Reset(
"ntv2nub://1.2.3.4/path/to/doc/?one=1");
1009 specParser.
Reset(
"ntv2nub://1.2.3.4/path/to/doc?one=1");
1010 specParser.
Reset(
"ntv2nub://1.2.3.4/path/to/doc/?one=1&two");
1011 specParser.
Reset(
"ntv2nub://1.2.3.4/path/to/doc?one=1&two");
1012 specParser.
Reset(
"ntv2nub://50.200.250.300");
1013 specParser.
Reset(
"ntv2nub://fully.qualified.domain.name.com/path/to/doc/?one=1&two");
1014 specParser.
Reset(
"ntv2nub://fully.qualified.domain.name.edu:badport/path/to/doc/?one=1&two");
1015 specParser.
Reset(
"ntv2nub://fully.qualified.domain.name.info:5544/path/to/doc/?one=1&two");
1016 specParser.
Reset(
"ntv2nub://fully.qualified.domain.name.org/path/to/doc/?one=1&two");
1017 specParser.
Reset(
"ntv2nub://fully.qualified.domain.name.nz:badport/path/to/doc/?one=1&two");
1018 specParser.
Reset(
"ntv2nub://fully.qualified.domain.name.au:000004/path/to/doc/?one=1&two");
1019 specParser.
Reset(
"ntv2nub://fully.qualified.domain.name.ch:4/corvid88");
1020 specParser.
Reset(
"ntv2nub://fully.qualified.domain.name.cn:4/00T64450");
1021 specParser.
Reset(
"ntv2nub://fully.qualified.domain.name.ru:4/2");
1022 specParser.
Reset(
"ntv2nub://fully.qualified.domain.name.co.uk:4/00000000000000000000000000000001");
1023 specParser.
Reset(
"ntv2nub://fully.qualified.domain.name.com:4/0000000000000000000000000000000001");
1024 specParser.
Reset(
"ntv2://swdevice/?" 1026 "&supportlog=file%3A%2F%2F%2FUsers%2Fdemo%2FDesktop%2FAJAWatcherSupport.log" 1027 "&sdram=file%3A%2F%2F%2FUsers%2Fdemo%2FDesktop%2FSDRAMsnapshot.dat");
1029 #endif // defined(_DEBUG) 1031 #if defined(MSWindows) 1032 static string WinErrStr (
const DWORD inErr)
1034 string result(
"foo");
1036 const DWORD res(FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER
1037 | FORMAT_MESSAGE_FROM_SYSTEM
1038 | FORMAT_MESSAGE_IGNORE_INSERTS,
1041 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1047 result =
reinterpret_cast<const char *
>(lpMsgBuf);
1048 LocalFree(lpMsgBuf);
1055 #if !defined(NTV2_PREVENT_PLUGIN_LOAD) 1068 static bool LoadPlugin (
const string & path,
const string & folderPath,
NTV2PluginPtr & outPtr,
string & outErrMsg,
const bool inUseStdout);
1071 #if defined(MSWindows) 1072 NTV2Plugin (HMODULE handle,
const string & path,
const bool useStdout);
1073 inline operator HMODULE()
const {
return mHandle;}
1075 NTV2Plugin (
void * handle,
const string & path,
const bool useStdout);
1076 inline operator void*()
const {
return mHandle;}
1079 inline bool isLoaded (
void)
const {
return mHandle && !mPath.empty() ?
true :
false;}
1080 void * addressForSymbol (
const string & inSymbol,
string & outErrorMsg);
1086 inline bool useStdout(
void) {
return mUseStdout;}
1088 #if defined(MSWindows) 1100 ostringstream loadErr;
1101 #if defined(AJABareMetal) 1103 #elif defined(MSWindows) 1105 std::wstring dllsFolderW;
1107 if (!AddDllDirectory(dllsFolderW.c_str()))
1109 loadErr <<
"AddDllDirectory '" << path <<
"' failed: " << WinErrStr(::GetLastError());
1112 HMODULE h = ::LoadLibraryExA(LPCSTR(path.c_str()),
AJA_NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
1114 loadErr <<
"Unable to open '" << path <<
"': " << WinErrStr(::GetLastError());
1115 #else // MacOS or Linux 1117 void * h = ::dlopen(path.c_str(), RTLD_LAZY);
1120 const char * pErrorStr(::dlerror());
1121 const string errStr (pErrorStr ? pErrorStr :
"");
1122 loadErr <<
"Unable to open '" << path <<
"': " << errStr;
1124 #endif // MacOS or Linux 1125 if (!loadErr.str().empty())
1126 outErrMsg = loadErr.str();
1129 outPtr =
new NTV2Plugin(h, path, inUseStdout);
1133 NTV2Plugin::NTV2Plugin()
1151 #if defined(MSWindows) 1162 P_NOTE(
"Dynamic/shared library '" << mPath <<
"' (" <<
INSTP(mHandle) <<
") loaded, " 1169 #if defined(AJABareMetal) 1171 #elif !defined(MSWindows) 1173 #else // macOS or Linux 1174 ::FreeLibrary(mHandle);
1177 P_NOTE(
"Dynamic/shared library '" << mPath <<
"' (" <<
INSTP(mHandle) <<
") unloaded, " 1185 outErrorMsg.clear();
1188 if (inSymbolName.empty())
1192 #if defined(AJABareMetal) 1194 #elif defined(MSWindows) 1195 result =
reinterpret_cast<void*
>(::GetProcAddress(reinterpret_cast<HMODULE>(mHandle), inSymbolName.c_str()));
1197 err <<
"'GetProcAddress' failed for '" << inSymbolName <<
"': " << WinErrStr(::GetLastError());
1198 #else // MacOS or Linux 1199 result = ::dlsym(mHandle, inSymbolName.c_str());
1201 {
const char * pErrorStr(::dlerror());
1202 const string errStr (pErrorStr ? pErrorStr :
"");
1203 err <<
"'dlsym' failed for '" << inSymbolName <<
"': " << errStr;
1205 #endif // MacOS or Linux 1206 outErrorMsg = err.str();
1225 static void Terminate (
void);
1226 static inline void EnableDebugging (
const bool inEnable =
true) {sDebugRegistry = inEnable;}
1232 bool loadPlugin (
const string & path,
const string & folderPath,
NTV2PluginPtr & outPtr,
string & errMsg,
const bool useStdout);
1233 bool unloadPlugin (
const string & path,
string & errMsg);
1234 bool pluginIsLoaded (
const string & path);
1235 bool pluginForPath (
const string & path,
NTV2PluginPtr & outHandle);
1238 bool hasPath (
const string & path);
1239 bool indexForPath (
const string & path,
size_t & outIndex);
1240 ULWord countForPath (
const string & path);
1241 uint32_t * refConForPath (
const string & path);
1242 inline bool useStdout (
void)
const {
return DebuggingEnabled();}
1245 typedef map<string, NTV2PluginPtr> NTV2PluginMap;
1249 NTV2PluginMap mPluginMap;
1254 static void Monitor (
AJAThread * pThread,
void * pContext);
1255 void monitor (
void);
1258 static bool sDebugRegistry;
1262 AJALock PluginRegistry::sMutex;
1263 bool PluginRegistry::sDebugRegistry(
false);
1280 void PluginRegistry::Monitor (
AJAThread * pThread,
void * pContext)
1282 PluginRegistry * pObj (reinterpret_cast<PluginRegistry*>(pContext));
1288 : mQuitMonitor(
false)
1290 P_NOTE (
"PluginRegistry " <<
INSTP(
this) <<
" constructed");
1291 mPluginCounts.reserve(256);
1292 for (
size_t num(0); num < 256; num++)
1293 mPluginCounts.push_back(0);
1294 mCompareCounts = mPluginCounts;
1295 mMonitor.
Attach(Monitor,
this);
1302 mQuitMonitor =
true;
1303 while (mMonitor.
Active())
1313 {
P_FAIL(
"empty path");
return false;}
1320 {
P_WARN(
INSTP(
this) <<
": '" << path <<
"': 'pluginForPath' returned false, but 'hasPath' returned true, count=" <<
countForPath(path));}
1323 {
P_FAIL(msg);
return false;}
1324 P_NOTE(
INSTP(
this) <<
": Dynamic/shared library '" << path <<
"' loaded");
1325 mPluginMap[path] = outPtr;
1326 mPluginPaths.push_back(path);
1327 mPluginCounts.at(mPluginPaths.size()-1) = 0;
1338 {
P_FAIL(
INSTP(
this) <<
": '" << path <<
"' requested to unload, but not loaded");
return false;}
1339 mPluginMap.erase(path);
1340 P_NOTE(
INSTP(
this) <<
": '" << path <<
"' unloaded");
1347 return mPluginMap.find(path) != mPluginMap.end();
1353 NTV2PluginMap::const_iterator it(mPluginMap.find(path));
1354 if (it == mPluginMap.end())
1357 outHandle = it->second;
1365 for (NTV2PluginMap::const_iterator it(mPluginMap.begin()); it != mPluginMap.end(); ++it)
1366 result.push_back(it->first);
1374 for (
size_t ndx(0); ndx < mPluginPaths.size(); ndx++)
1376 const string path (mPluginPaths.at(ndx));
1380 oss <<
"\t" << (p->
isLoaded() ?
"loaded" :
"unloaded");
1382 oss <<
"\t" <<
"---";
1383 result.push_back(oss.str());
1397 for (outIndex = 0; outIndex < mPluginPaths.size(); outIndex++)
1398 if (path == mPluginPaths.at(outIndex))
1408 return &mPluginCounts[ndx];
1416 return mPluginCounts.at(ndx);
1420 void PluginRegistry::monitor (
void)
1422 P_NOTE(
"PluginRegistry " <<
INSTP(
this) <<
" monitor started");
1423 ostringstream oss; oss <<
"PluginReg" <<
HEX0N(uint32_t(uint64_t(
this)),8);
1425 while (!mQuitMonitor)
1429 for (
size_t ndx(0); ndx < mPluginPaths.size(); ndx++)
1431 const uint32_t oldCount(mCompareCounts.at(ndx)), newCount(mPluginCounts.at(ndx));
1432 if (newCount != oldCount)
1434 string errMsg, path(mPluginPaths.at(ndx));
1435 if (newCount > oldCount)
1436 {
P_NOTE(
"PluginRegistry " <<
INSTP(
this) <<
": Plugin '" << path <<
"' utilization " 1437 <<
"increased from " <<
DEC(oldCount) <<
" to " <<
DEC(newCount));}
1440 P_NOTE(
"PluginRegistry " <<
INSTP(
this) <<
": Plugin '" << path <<
"' utilization " 1441 <<
"decreased from " <<
DEC(oldCount) <<
" to " <<
DEC(newCount));
1445 mCompareCounts.at(ndx) = newCount;
1451 P_NOTE(
"PluginRegistry " <<
INSTP(
this) <<
" monitor stopped");
1469 void *
refCon (
void)
const;
1473 void *
getSymbolAddress (
const string & inSymbolName,
string & outErrorMsg);
1487 mutable string errMsg;
1492 static string mbedErrStr (
const int mbedtlsReturnCode);
1520 { cout <<
"## NOTE: Original params for '" <<
pluginPath() <<
"':" << endl;
1521 originalParams.
Print(cout,
false) << endl;
1526 { cout <<
"## NOTE: Final params for '" <<
pluginPath() <<
"':" << endl;
1527 mDict.
Print(cout,
false) << endl;
1543 mbedtls_strerror (mbedtlsReturnCode, errBuff, errBuff);
1555 for (
size_t lineNdx(0); lineNdx < lines.size(); lineNdx++)
1557 string line (lines.at(lineNdx));
1558 const bool indented (line.empty() ?
false : line.at(0) ==
' ');
1563 if (keyValPair.size() != 2)
1565 if (keyValPair.size() == 1)
1567 keyPrefix = keyValPair.at(0);
1572 PLGFAIL(
"cert info line " <<
DEC(lineNdx+1) <<
" '" << line <<
"' has " 1573 <<
DEC(keyValPair.size()) <<
" column(s) -- expected 2");
1576 string key(keyValPair.at(0)), val(keyValPair.at(1));
1578 {
PLGFAIL(
"cert info line " <<
DEC(lineNdx+1) <<
" '" << line <<
"' empty key for value '" << val <<
"'");
continue;}
1579 if (indented && !keyPrefix.empty())
1580 {
aja::strip(key); key = keyPrefix +
": " + key;}
1598 for (
size_t ndx(0); ndx < pairs.size(); ndx++)
1600 string assignment (pairs.at(ndx));
1601 if (assignment.find(
'=') == string::npos)
1603 if (!lastKey.empty())
1609 if (pieces.size() != 2)
1610 {
PLGFAIL(
"'" << inParentKey <<
"' assignment '" << assignment <<
"' has " << pieces.size() <<
" component(s) -- expected 2");
continue;}
1611 lastKey = pieces.at(0);
1612 string val(pieces.at(1));
1624 if (!queryStr.empty())
1625 if (queryStr[0] ==
'?')
1626 queryStr.erase(0,1);
1627 PLGDBG(
"Query: '" << queryStr <<
"'");
1631 string str(*it), key, value;
1632 if (str.find(
"=") == string::npos)
1635 outQueryParams.
insert(key, value);
1636 PLGDBG(
"'" << key <<
"' = ''");
1643 if (pieces.size() > 1)
1644 value = pieces.at(1);
1646 {
PLGWARN(
"Empty key '" << key <<
"'");
continue;}
1647 if (outQueryParams.
hasKey(key))
1648 PLGDBG(
"Param '" << key <<
"' value '" << outQueryParams.
valueForKey(key) <<
"' to be replaced with '" << value <<
"'");
1657 outErrorMsg.clear();
1675 if (outPath.empty())
1677 PLGDBG(
"AJA plugin path is '" << outPath <<
"'");
1679 return !outPath.empty();
1689 {
P_FAIL(
"Missing scheme -- params: " << mDict);
return false;}
1693 return !outName.empty();
1714 const size_t maxBufSize = 512*1024*1024;
1717 dllF.open(
pluginPath(), std::ios::in | std::ios::binary);
1722 ifstream::pos_type curOffset(dllF.tellg());
1723 if (
int(curOffset) == -1)
1725 size_t size = size_t(curOffset);
1728 if (size > maxBufSize)
1729 {
P_FAIL(
"EOF not reached in plugin file '" <<
pluginPath() <<
"' -- over 500MB in size?");
return fail();}
1733 if (!dllF.seekg(0, ios_base::beg))
1734 {
P_FAIL(
"Could not seek back to start of plugin file '" <<
pluginPath() <<
"'");
return fail();}
1736 {
P_FAIL(
"EOF not reached in plugin file '" <<
pluginPath() <<
"' -- over 500MB in size?");
return fail();}
1737 tmp.
Truncate(
size_t(dllF.gcount()));
1741 ifstream sigF(
pluginSigPath().c_str(), std::ios::in | std::ios::binary);
1745 {
P_FAIL(
"EOF not reached in signature file '" <<
pluginSigPath() <<
"' -- over 500MB in size?");
return fail();}
1746 tmp.
Truncate(
size_t(sigF.gcount()));
1757 NTV2Buffer checksumFromSigFile, x509CertFromSigFile, signature;
1768 mbedtls_x509_crt crt;
1769 mbedtls_x509_crt_init(&crt);
1770 int ret = mbedtls_x509_crt_parse(&crt, x509CertFromSigFile, x509CertFromSigFile);
1773 mbedtls_x509_crt_free(&crt);
1781 int msgLength (mbedtls_x509_crt_info (msgBuff, msgBuff,
"", &crt));
1782 string msg (msgBuff,
size_t(msgLength));
1784 {
P_FAIL(
"'mbedtls_x509_crt_info' returned no info for X509 cert found in '" <<
pluginSigPath() <<
"'");
1788 cout <<
"## DEBUG: Raw X509 certificate info extracted from signature file '" <<
pluginSigPath() <<
"':" << endl
1789 <<
" " << msg << endl;
1793 { cout <<
"## NOTE: X509 certificate info extracted from signature file '" <<
pluginSigPath() <<
"':" << endl;
1794 certInfo.
Print(cout,
false) << endl;
1796 if (certInfo.
hasKey(
"issuer name"))
1799 if (certInfo.
hasKey(
"subject name"))
1807 { cout <<
"## NOTE: 'issuer name' info:" << endl;
1808 issuerInfo.
Print(cout,
false) << endl;
1811 { cout <<
"## NOTE: 'subject name' info:" << endl;
1812 subjectInfo.
Print(cout,
false) << endl;
1831 ret = mbedtls_md_file (mbedtls_md_info_from_type(MBEDTLS_MD_SHA256),
pluginPath().c_str(), checksumFromDLL);
1836 if (
isVerbose()) {
string str;
if (checksumFromDLL.
toHexString(str)) cout <<
"## DEBUG: Digest: " << str << endl;}
1839 ret = mbedtls_pk_verify (&crt.pk, MBEDTLS_MD_SHA256,
1841 signature, signature);
1846 mbedtls_x509_crt_free(&crt);
1847 P_DBG(
"'mbedtls_pk_verify' succeeded for '" <<
pluginPath() <<
"' -- signature valid");
1867 if (regInfo.
empty())
1876 for (
size_t ndx(0); ndx < reqKeys.size(); ndx++)
1877 if (!regInfo.
hasKey(reqKeys.at(ndx)))
1878 missingRegInfoKeys.push_back(reqKeys.at(ndx));
1879 if (!missingRegInfoKeys.empty())
1880 {
P_FAIL(
"'" <<
pluginPath() <<
"': missing key(s) in registration info: '" 1881 <<
aja::join(missingRegInfoKeys,
"','") <<
"'");
1898 if (onReg != onCert)
1901 <<
"') \"" << onCert <<
"\" from X509 certificate 'Issuer' in '" <<
pluginSigPath() <<
"'");
1904 if (cnReg != cnCert)
1907 <<
"') \"" << cnCert <<
"\" from X509 certificate 'Issuer' in '" <<
pluginSigPath() <<
"'");
1910 if (ouReg != ouCert)
1913 <<
"') \"" << ouCert <<
"\" from X509 certificate 'Subject' in '" <<
pluginSigPath() <<
"'");
1916 if (myVers != plVers)
1918 <<
"\" doesn't match client SDK version '" << myVers <<
"'");
1922 if (fingerprint != ajaFingerprint)
1924 <<
"Issuer serial: " << fingerprint <<
"|AJA serial: " << ajaFingerprint);
1953 return mpPlugin && mValidated;
1960 cout <<
"0 plugins" << endl;
1961 else if (paths.size() == 1)
1962 cout <<
"1 plugin: " << paths.at(0) << endl;
1963 else cout <<
DEC(paths.size()) <<
" plugins:" << endl <<
aja::join(paths,
"\n") << endl;
1965 #endif // !defined(NTV2_PREVENT_PLUGIN_LOAD) 1983 {cout << __FILE__ <<
"(" << __LINE__ <<
"):" <<
AJAFUNC <<
":" << endl;
mParams.
Print(cout,
false) << endl;}
1998 size_t oldCount(
mParams.
size()), updated(0), added(0);
2008 NBSDBG(
DEC(oldCount) <<
" param(s) removed, replaced with " << inNewParams);
2022 while (nums.size() > 3)
2030 static const string sAJAFingerprint (
"70:1A:37:93:FA:4F:34:30:58:55:51:0C:01:4E:45:7C:BE:5B:41:65");
2031 string result(sAJAFingerprint);
2085 oss << (
IsConnected() ?
"Connected" :
"Disconnected");
2087 oss <<
" to '" <<
Name() <<
"'";
2096 strs.push_back(
string(
"from '") + fName +
"'");
2099 if (!hostName.empty())
2100 {strs.push_back(
"on"); strs.push_back(
string(
"'") + hostName +
"'");}
2127 { (
void) autoCircData;
2132 { (
void) eInterrupt; (
void) timeOutMs;
2136 #if !defined(NTV2_DEPRECATE_16_3) 2138 { (
void) bitFileType;
2139 ::memset(&bitFileInfo, 0,
sizeof(bitFileInfo));
2145 ::memset(&buildInfo, 0,
sizeof(buildInfo));
2150 const UWord signalMask,
const bool testPatDMAEnb,
const ULWord testPatNum)
2151 { (
void) channel; (
void) testPatternFBF; (
void) signalMask; (
void) testPatDMAEnb; (
void) testPatNum;
2156 { (
void) numRegs; (
void) outFailedRegNum; (
void) outRegs;
2162 outDriverVersion = 0xFFFFFFFF;
2165 #endif // !defined(NTV2_DEPRECATE_16_3) 2169 const ULWord inNumSegments,
const ULWord inSegmentHostPitch,
2170 const ULWord inSegmentCardPitch,
const bool inSynchronous)
2171 { (
void) inDMAEngine; (
void) inIsRead; (
void) inFrameNumber; (
void) inOutFrameBuffer;
2172 (
void) inCardOffsetBytes; (
void) inNumSegments; (
void) inSegmentHostPitch;
2173 (
void) inSegmentCardPitch; (
void) inSynchronous;
2178 { (
void) pInMessage;
2196 outSupported.clear();
2214 #if defined(NTV2_PREVENT_PLUGIN_LOAD) 2242 #if defined(NTV2_PREVENT_PLUGIN_LOAD) 2266 if (parser.HasErrors())
2268 NBSFAIL(parser.Error() <<
" in URL:\n" << inURL);
2269 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.
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.
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)
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
bool isLoaded(void) const
NTV2StringSet::const_iterator NTV2StringSetConstIter
#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.
std::vector< std::string > NTV2StringList
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)
#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]. ...
NTV2StringList::const_iterator NTV2StringListConstIter
std::set< std::string > NTV2StringSet
#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.