AJA NTV2 SDK  17.0.1.1246
NTV2 SDK 17.0.1.1246
ntv2nubaccess.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
7 #include "ajatypes.h"
8 #include "ntv2utils.h"
9 #include "ntv2nubaccess.h"
10 #include "ntv2publicinterface.h"
11 #include "ntv2version.h"
12 #include "ajabase/system/debug.h"
13 #include "ajabase/common/common.h"
14 #include "ajabase/system/info.h"
16 #include <iomanip>
17 #if defined(AJAMac)
18  #include <CoreFoundation/CoreFoundation.h>
19  #include <dlfcn.h>
20  #define DLL_EXTENSION ".dylib"
21  #define FIRMWARE_FOLDER "Firmware/"
22 #elif defined(AJALinux)
23  #include <dlfcn.h>
24  #define DLL_EXTENSION ".so"
25  #define FIRMWARE_FOLDER "firmware/"
26 #elif defined(MSWindows)
27  #define DLL_EXTENSION ".dll"
28  #define FIRMWARE_FOLDER "Firmware\\"
29 #elif defined(AJABareMetal)
30  #define DLL_EXTENSION ".dll"
31  #define FIRMWARE_FOLDER "Firmware\\"
32 #endif
33 
34 using namespace std;
35 
36 #define INSTP(_p_) xHEX0N(uint64_t(_p_),16)
37 #define NBFAIL(__x__) AJA_sERROR (AJA_DebugUnit_RPCClient, INSTP(this) << "::" << AJAFUNC << ": " << __x__)
38 #define NBWARN(__x__) AJA_sWARNING(AJA_DebugUnit_RPCClient, INSTP(this) << "::" << AJAFUNC << ": " << __x__)
39 #define NBNOTE(__x__) AJA_sNOTICE (AJA_DebugUnit_RPCClient, INSTP(this) << "::" << AJAFUNC << ": " << __x__)
40 #define NBINFO(__x__) AJA_sINFO (AJA_DebugUnit_RPCClient, INSTP(this) << "::" << AJAFUNC << ": " << __x__)
41 #define NBDBG(__x__) AJA_sDEBUG (AJA_DebugUnit_RPCClient, INSTP(this) << "::" << AJAFUNC << ": " << __x__)
42 #define NBCFAIL(__x__) AJA_sERROR (AJA_DebugUnit_RPCClient, AJAFUNC << ": " << __x__)
43 #define NBCWARN(__x__) AJA_sWARNING(AJA_DebugUnit_RPCClient, AJAFUNC << ": " << __x__)
44 #define NBCNOTE(__x__) AJA_sNOTICE (AJA_DebugUnit_RPCClient, AJAFUNC << ": " << __x__)
45 #define NBCINFO(__x__) AJA_sINFO (AJA_DebugUnit_RPCClient, AJAFUNC << ": " << __x__)
46 #define NBCDBG(__x__) AJA_sDEBUG (AJA_DebugUnit_RPCClient, AJAFUNC << ": " << __x__)
47 #define NBSFAIL(__x__) AJA_sERROR (AJA_DebugUnit_RPCServer, AJAFUNC << ": " << __x__)
48 #define NBSWARN(__x__) AJA_sWARNING(AJA_DebugUnit_RPCServer, AJAFUNC << ": " << __x__)
49 #define NBSNOTE(__x__) AJA_sNOTICE (AJA_DebugUnit_RPCServer, AJAFUNC << ": " << __x__)
50 #define NBSINFO(__x__) AJA_sINFO (AJA_DebugUnit_RPCServer, AJAFUNC << ": " << __x__)
51 #define NBSDBG(__x__) AJA_sDEBUG (AJA_DebugUnit_RPCServer, AJAFUNC << ": " << __x__)
52 
53 
54 string NTV2Dictionary::valueForKey (const string & inKey) const
55 {
56  DictConstIter it(mDict.find(inKey));
57  if (it == mDict.end())
58  return "";
59  return it->second;
60 }
61 
62 uint16_t NTV2Dictionary::u16ValueForKey (const string & inKey, const uint16_t inDefault) const
63 {
64  string str(valueForKey(inKey));
65  if (str.empty())
66  return inDefault;
67  if (str.find("0x") == 0 || str.find("0X") == 0)
68  {
69  str.erase(0,2);
70  if (str.empty())
71  return inDefault;
72  return uint16_t(aja::stoul(str, AJA_NULL, 16));
73  }
74  if (str.find("x") == 0 || str.find("X") == 0)
75  {
76  str.erase(0,1);
77  if (str.empty())
78  return inDefault;
79  return uint16_t(aja::stoul(str, AJA_NULL, 16));
80  }
81  if (str.find("o") == 0 || str.find("O") == 0)
82  {
83  str.erase(0,1);
84  if (str.empty())
85  return inDefault;
86  return uint16_t(aja::stoul(str, AJA_NULL, 8));
87  }
88  if (str.find("b") == 0 || str.find("B") == 0)
89  {
90  str.erase(0,1);
91  if (str.empty())
92  return inDefault;
93  return uint16_t(aja::stoul(str, AJA_NULL, 2));
94  }
95  return uint16_t(aja::stoul(str, AJA_NULL, 10));
96 }
97 
98 ostream & NTV2Dictionary::Print (ostream & oss, const bool inCompact) const
99 {
100  if (inCompact)
101  for (DictConstIter it(mDict.begin()); it != mDict.end(); )
102  {
103  const string & key(it->first), val(it->second), quote(val.find(' ') != string::npos ? "'" : "");
104  oss << key << "=" << quote << val << quote;
105  if (++it != mDict.end())
106  oss << " ";
107  }
108  else if (empty())
109  oss << "0 entries";
110  else
111  {
112  const int kyWdth(int(largestKeySize()+0)), valWdth(int(largestValueSize()+0));
113  oss << string(size_t(kyWdth), '-') << " " << string(size_t(valWdth), '-') << endl;
114  for (DictConstIter it(mDict.begin()); it != mDict.end(); )
115  {
116  const string & key(it->first), val(it->second);
117  oss << std::setw(kyWdth) << key << " : " << val;
118  if (++it != mDict.end())
119  oss << endl;
120  }
121  }
122  return oss;
123 }
124 
126 {
127  NTV2StringSet result;
128  for (DictConstIter it(mDict.begin()); it != mDict.end(); ++it)
129  result.insert(it->first);
130  return result;
131 }
132 
134 {
135  size_t result(0);
136  for (DictConstIter it(mDict.begin()); it != mDict.end(); ++it)
137  if (it->first.length() > result)
138  result = it->first.length();
139  return result;
140 }
141 
143 {
144  size_t result(0);
145  for (DictConstIter it(mDict.begin()); it != mDict.end(); ++it)
146  if (it->second.length() > result)
147  result = it->second.length();
148  return result;
149 }
150 
152 {
153  size_t numUpdated(0);
154  for (DictConstIter it(inDict.mDict.begin()); it != inDict.mDict.end(); ++it)
155  if (hasKey(it->first))
156  {mDict[it->first] = it->second; numUpdated++;}
157  return numUpdated;
158 }
159 
161 {
162  size_t numAdded(0);
163  for (DictConstIter it(inDict.mDict.begin()); it != inDict.mDict.end(); ++it)
164  if (!hasKey(it->first))
165  {mDict[it->first] = it->second; numAdded++;}
166  return numAdded;
167 }
168 
169 
171 {
172  Reset(inSpec);
173 }
174 
175 void NTV2DeviceSpecParser::Reset (const string inSpec)
176 {
177  mErrors.clear();
178  mResult.clear();
179  mQueryParams.clear();
180  mPos = 0;
181  mSpec = inSpec;
182  if (!mSpec.empty())
183  Parse(); // Go ahead and parse it
184 }
185 
186 string NTV2DeviceSpecParser::Resource (const bool inStripLeadSlash) const
187 {
188  string rsrc (Result(kConnectParamResource));
189  if (rsrc.empty())
190  return rsrc;
191  if (!inStripLeadSlash)
192  return rsrc;
193  if (rsrc.at(0) == '/')
194  rsrc.erase(0,1);
195  return rsrc;
196 }
197 
198 void NTV2DeviceSpecParser::Parse (void)
199 {
200  // A run of 3 consecutive letters that match "ntv" -- probably a scheme
201  // A run of 1 or 2 decimal digits -- probably a local device index number
202  // "0X" or "0x":
203  // - maybe a hexadecimal 32-bit value -- a local device ID
204  // - maybe a hexadecimal 64-bit value -- a local device serial number
205  // A run of 8 or 9 alphanumeric chars -- probably a local device serial number
206  ostringstream err;
207  string tokDevID, tokIndexNum, tokScheme, tokSerial, tokModelName;
208  size_t posDevID(0), posIndexNum(0), posScheme(0), posSerial(0), posModelName(0);
209  bool isSerial(ParseSerialNum(posSerial, tokSerial)), isScheme(ParseScheme(posScheme, tokScheme));
210  bool isIndexNum(ParseDecNumber(posIndexNum, tokIndexNum)), isDeviceID(ParseDeviceID(posDevID, tokDevID));
211  bool isModelName(ParseModelName(posModelName, tokModelName));
212  if (isScheme && tokScheme == kLegalSchemeNTV2Local)
213  { // Re-parse serial#, index#, deviceID, modelName from just past "://"...
214  posDevID = posIndexNum = posSerial = posModelName = posScheme;
215  isSerial = ParseSerialNum(posSerial, tokSerial);
216  isIndexNum = ParseDecNumber(posIndexNum, tokIndexNum);
217  isDeviceID = ParseDeviceID(posDevID, tokDevID);
218  isModelName = ParseModelName(posModelName, tokModelName);
219  }
220  do
221  {
222  if (isModelName)
223  {
224  mPos = posModelName;
226  mResult.insert(kConnectParamDevModel, tokModelName);
227  break;
228  }
229  if (isSerial)
230  { // Final serial number checks...
231  bool converted(false);
232  mPos = posSerial;
233  if (tokSerial.length() == 18) // 64-bit hex value?
234  {
235  // Convert numeric serial number into character string...
236  const bool hasLeading0X (tokSerial.find("0X") == 0 || tokSerial.find("0x") == 0);
237  const string hex64(tokSerial.substr(hasLeading0X ? 2 : 0, 16));
238  const ULWord64 serNum64(aja::stoull(hex64, AJA_NULL, 16));
239  string serTxt; // (CNTV2Card::SerialNum64ToString(serNum64));
240  for (size_t ndx(0); ndx < 8; ndx++)
241  serTxt += char(serNum64 >> ((7-ndx)*8));
242  //cerr << "Converted '" << tokSerial << "' into '" << serTxt << "'" << endl;
243  tokSerial = serTxt;
244  converted = true;
245  }
246  // Check for illegal characters in serial number:
247  for (size_t ndx(0); ndx < tokSerial.length(); ndx++)
248  { char ch(tokSerial.at(ndx));
249  if ( ! ( ( (ch >= '0') && (ch <= '9') ) ||
250  ( (ch >= 'A') && (ch <= 'Z') ) ||
251  ( (ch >= 'a') && (ch <= 'z') ) ||
252  (ch == ' ') || (ch == '-') ) )
253  {
254  err << "Illegal serial number character '" << (ch ? ch : '?') << "' (" << xHEX0N(UWord(ch),2) << ")";
255  AddError(err.str());
256  mPos -= converted ? 16 : 8; mPos += ndx * (converted ? 2 : 1) + (converted ? 1 : 0);
257  break;
258  }
259  }
260  mResult.insert(kConnectParamDevSerial, tokSerial);
262  break;
263  }
264  if (isDeviceID)
265  {
266  mPos = posDevID;
267  mResult.insert(kConnectParamDevID, tokDevID);
269  break;
270  }
271  if (isIndexNum)
272  {
273  mPos = posIndexNum;
274  mResult.insert(kConnectParamDevIndex, tokIndexNum);
276  break;
277  }
278  if (!isScheme || (isScheme && tokScheme == kLegalSchemeNTV2Local))
279  { // No such local device
280  err << "Invalid local device specification";
281  AddError(err.str());
282  mPos += isScheme ? 12 : 0;
283  break;
284  }
285  if (isScheme)
286  { // Continue parsing URLspec...
287  mPos = posScheme;
288  if (!IsSupportedScheme(tokScheme))
289  {err << "Unsupported scheme '" << tokScheme << "'"; AddError(err.str()); mPos -= 3; break;}
290  // "ntv2://swdevice/?"
291  // "nosharedmemory"
292  // "&supportlog=file%3A%2F%2F%2FUsers%2Fdemo%2FDesktop%2FAJAWatcherSupport.log"
293  // "&sdram=file%3A%2F%2F%2FUsers%2Fdemo%2FDesktop%2FSDRAMsnapshot.dat");
294  // Host[port]/[resource[?query]]
295  size_t posURL(posScheme), posRsrc(0);
296  string host, port, rsrcPath;
297  if (!ParseHostAddressAndPortNumber(posURL, host, port))
298  {mPos = posURL; AddError("Bad host address or port number"); break;}
299  mPos = posURL;
300  mResult.insert(kConnectParamScheme, tokScheme);
301  mResult.insert(kConnectParamHost, host);
302  if (!port.empty())
303  mResult.insert(kConnectParamPort, port);
304 
305  // Parse resource path...
306  posRsrc = mPos;
307  if (ParseResourcePath(posRsrc, rsrcPath))
308  {mPos = posRsrc; mResult.insert(kConnectParamResource, rsrcPath);}
309  // Parse query...
310  size_t posQuery(mPos);
311  NTV2Dictionary params;
312  if (ParseQuery(posQuery, params))
313  {
314  mResult.insert(kConnectParamQuery, DeviceSpec().substr(mPos, posQuery-mPos+1));
315  mQueryParams = params;
316  mPos = posQuery;
317  }
318  if (mPos < SpecLength())
319  {err << "Extra character(s) at " << DEC(mPos); AddError(err.str()); break;}
320  }
321  } while (false);
322  #if defined(_DEBUG)
323  ostringstream oss;
324  if (Successful())
325  {oss << "NTV2DeviceSpecParser::Parse success: '" << DeviceSpec() << "' -- "; Print(oss); AJA_sDEBUG(AJA_DebugUnit_Application, oss.str());}
326  else
327  {oss << "NTV2DeviceSpecParser::Parse failed: "; PrintErrors(oss); AJA_sERROR(AJA_DebugUnit_Application, oss.str());}
328  #endif // defined(_DEBUG)
329 } // Parse
330 
331 ostream & NTV2DeviceSpecParser::Print (ostream & oss, const bool inDumpResults) const
332 {
333  oss << (IsLocalDevice() ? "local " : "") << "device";
334  if (HasResult(kConnectParamDevSerial))
335  oss << " serial '" << DeviceSerial() << "'";
336  else if (HasResult(kConnectParamDevModel))
337  oss << " model '" << DeviceModel() << "'";
338  else if (HasResult(kConnectParamDevID))
339  oss << " ID '" << DeviceID() << "'";
340  else if (HasResult(kConnectParamDevIndex))
341  oss << " " << DeviceIndex();
342  if (HasResult(kConnectParamHost))
343  oss << " host '" << Result(kConnectParamHost) << "'";
344  if (HasResult(kConnectParamPort))
345  oss << " port " << Result(kConnectParamPort);
346  if (HasResult(kConnectParamResource))
347  oss << " resource '" << Result(kConnectParamResource) << "'";
348  if (HasResult(kConnectParamQuery))
349  oss << " query '" << Result(kConnectParamQuery) << "'";
350  if (inDumpResults)
351  {oss << endl; Results().Print(oss, /*compact?*/false);}
352  return oss;
353 }
354 
356 {
357  ostringstream oss;
358  Print(oss);
359  return oss.str();
360 }
361 
363 {
364  uint64_t result(0);
366  return result;
367 }
368 
370 {
371  string devIDStr (Result(kConnectParamDevID));
372  if (devIDStr.find("0X") != string::npos)
373  devIDStr.erase(0,2); // Delete "0x"
374  ULWord u32 = ULWord(aja::stoull(devIDStr, AJA_NULL, 16));
375  return NTV2DeviceID(u32);
376 }
377 
379 {
380  string devIDStr (Result(kConnectParamDevIndex));
381  UWord u16 = UWord(aja::stoul(devIDStr));
382  return u16;
383 }
384 
385 ostream & NTV2DeviceSpecParser::PrintErrors (ostream & oss) const
386 {
387  oss << DEC(ErrorCount()) << (ErrorCount() == 1 ? " error" : " errors") << (HasErrors() ? ":" : "");
388  if (HasErrors())
389  {
390  oss << endl
391  << DeviceSpec() << endl
392  << string(mPos ? mPos : 0,' ') << "^" << endl;
393  for (size_t num(0); num < ErrorCount(); )
394  {
395  oss << Error(num);
396  if (++num < ErrorCount())
397  oss << endl;
398  }
399  }
400  return oss;
401 }
402 
403 bool NTV2DeviceSpecParser::ParseHexNumber (size_t & pos, string & outToken)
404 {
405  outToken.clear();
406  string tokHexNum;
407  while (pos < SpecLength())
408  {
409  const char ch(CharAt(pos));
410  if (tokHexNum.length() == 0)
411  {
412  if (ch != '0')
413  break;
414  ++pos; tokHexNum = ch;
415  }
416  else if (tokHexNum.length() == 1)
417  {
418  if (ch != 'x' && ch != 'X')
419  break;
420  ++pos; tokHexNum += ch;
421  }
422  else
423  {
424  if (!IsHexDigit(ch))
425  break;
426  ++pos; tokHexNum += ch;
427  }
428  }
429  if (tokHexNum.length() > 2) // At least 3 chars
430  {aja::upper(tokHexNum); outToken = tokHexNum;} // Force upper-case hex
431  return !outToken.empty();
432 }
433 
434 bool NTV2DeviceSpecParser::ParseDecNumber (size_t & pos, string & outToken)
435 {
436  outToken.clear();
437  string tokDecNum;
438  while (pos < SpecLength())
439  {
440  const char ch(CharAt(pos));
441  if (!IsDecimalDigit(ch))
442  break;
443  ++pos;
444  if (ch != '0' || tokDecNum != "0") // This prevents accumulating more than one leading zero
445  tokDecNum += ch;
446  }
447  if (tokDecNum.length() > 0) // At least 1 char
448  outToken = tokDecNum;
449  return !outToken.empty();
450 }
451 
452 bool NTV2DeviceSpecParser::ParseAlphaNumeric (size_t & pos, string & outToken, const std::string & inOtherChars)
453 {
454  outToken.clear();
455  string tokAlphaNum;
456  while (pos < SpecLength())
457  {
458  const char ch(CharAt(pos));
459  if (!IsLetter(ch) && !IsDecimalDigit(ch) && inOtherChars.find(ch) == string::npos)
460  break;
461  ++pos; tokAlphaNum += ch;
462  }
463  if (tokAlphaNum.length() > 1) // At least 2 chars
464  outToken = tokAlphaNum;
465  return !outToken.empty();
466 }
467 
468 bool NTV2DeviceSpecParser::ParseScheme (size_t & pos, string & outToken)
469 {
470  outToken.clear();
471  string rawScheme, tokScheme;
472  while (ParseAlphaNumeric(pos, rawScheme))
473  {
474  tokScheme = rawScheme;
475  char ch(CharAt(pos));
476  if (ch != ':')
477  break;
478  ++pos; tokScheme += ch;
479 
480  ch = CharAt(pos);
481  if (ch != '/')
482  break;
483  ++pos; tokScheme += ch;
484 
485  ch = CharAt(pos);
486  if (ch != '/')
487  break;
488  ++pos; tokScheme += ch;
489  break;
490  }
491  if (tokScheme.find("://") != string::npos) // Contains "://"
492  {aja::lower(rawScheme); outToken = rawScheme;} // Force lower-case
493  return !outToken.empty();
494 }
495 
496 bool NTV2DeviceSpecParser::ParseSerialNum (size_t & pos, string & outToken)
497 {
498  outToken.clear();
499  string tokAlphaNum, tokHexNum;
500  size_t posAlphaNum(pos), posHexNum(pos);
501  do
502  {
503  while (posAlphaNum < SpecLength())
504  {
505  const char ch(CharAt(posAlphaNum));
506  if (!IsUpperLetter(ch) && !IsDecimalDigit(ch) && ch != '-' && ch != ' ')
507  break;
508  ++posAlphaNum; tokAlphaNum += ch;
509  }
510  if (tokAlphaNum.length() < 2) // At least 2 upper-case chars
511  tokAlphaNum.clear();
512  else if (tokAlphaNum.length() == 8 || tokAlphaNum.length() == 9)
513  {pos = posAlphaNum; outToken = tokAlphaNum; break;}
514 
515  if (ParseHexNumber(posHexNum, tokHexNum))
516  if (tokHexNum.length() == 18) // 64-bit value!
517  {pos = posHexNum; outToken = tokHexNum;}
518  } while (false);
519  return !outToken.empty();
520 }
521 
522 bool NTV2DeviceSpecParser::ParseDeviceID (size_t & pos, string & outToken)
523 {
524  outToken.clear();
525  string tokHexNum;
526  if (!ParseHexNumber(pos, tokHexNum))
527  return false;
528  if (tokHexNum.length() != 10)
529  return false;
530  aja::upper(tokHexNum); // Fold to upper case
531 
532  // Check if it matches a known supported NTV2DeviceID...
534  NTV2StringSet devIDStrs;
535  for (NTV2DeviceIDSetConstIter it(allDevIDs.begin()); it != allDevIDs.end(); ++it)
536  {
537  ostringstream devID; devID << xHEX0N(*it,8);
538  string devIDStr(devID.str());
539  aja::upper(devIDStr);
540  devIDStrs.insert(devIDStr);
541  } // for each known/supported NTV2DeviceID
542  if (devIDStrs.find(tokHexNum) != devIDStrs.end())
543  outToken = tokHexNum; // Valid!
544  return !outToken.empty();
545 }
546 
547 bool NTV2DeviceSpecParser::ParseModelName (size_t & pos, string & outToken)
548 {
549  outToken.clear();
550  string tokName;
551  if (!ParseAlphaNumeric(pos, tokName))
552  return false;
553  aja::lower(tokName); // Fold to lower case
554 
555  // Check if it matches a known supported device model name...
557  NTV2StringSet modelNames;
558  for (NTV2DeviceIDSetConstIter it(allDevIDs.begin()); it != allDevIDs.end(); ++it)
559  {
560  string modelName(::NTV2DeviceIDToString(*it));
561  aja::lower(modelName);
562  modelNames.insert(modelName);
563  } // for each known/supported NTV2DeviceID
564  if (modelNames.find(tokName) != modelNames.end())
565  outToken = tokName; // Valid!
566  return !outToken.empty();
567 }
568 
569 bool NTV2DeviceSpecParser::ParseDNSName (size_t & pos, string & outDNSName)
570 {
571  outDNSName.clear();
572  string dnsName, name;
573  size_t dnsPos(pos);
574  char ch(0);
575  while (ParseAlphaNumeric(dnsPos, name, "_-")) // also allow '_' and '-'
576  {
577  if (!dnsName.empty())
578  dnsName += '.';
579  dnsName += name;
580  ch = CharAt(dnsPos);
581  if (ch != '.')
582  break;
583  ++dnsPos;
584  }
585  if (!dnsName.empty())
586  pos = dnsPos;
587  outDNSName = dnsName;
588  return !outDNSName.empty();
589 }
590 
591 bool NTV2DeviceSpecParser::ParseIPv4Address (size_t & pos, string & outIPv4)
592 {
593  outIPv4.clear();
594  string ipv4Name, num;
595  size_t ipv4Pos(pos);
596  char ch(0);
597  while (ParseDecNumber(ipv4Pos, num))
598  {
599  if (!ipv4Name.empty())
600  ipv4Name += '.';
601  ipv4Name += num;
602  ch = CharAt(ipv4Pos);
603  if (ch != '.')
604  break;
605  ++ipv4Pos;
606  }
607  if (!ipv4Name.empty())
608  pos = ipv4Pos;
609  outIPv4 = ipv4Name;
610  return !outIPv4.empty();
611 }
612 
613 bool NTV2DeviceSpecParser::ParseHostAddressAndPortNumber (size_t & pos, string & outAddr, string & outPort)
614 {
615  outAddr.clear(); outPort.clear();
616  // Look for a DNSName or an IPv4 dotted quad...
617  string dnsName, ipv4, port;
618  size_t dnsPos(pos), ipv4Pos(pos), portPos(0);
619  bool isDNS(ParseDNSName(dnsPos, dnsName)), isIPv4(ParseIPv4Address(ipv4Pos, ipv4));
620  if (!isDNS && !isIPv4)
621  {pos = dnsPos < ipv4Pos ? ipv4Pos : dnsPos; return false;}
622  // NOTE: It's possible to have both isIPv4 && isDNS true -- in this case, isIPv4 takes precedence:
623  if (isIPv4)
624  {outAddr = ipv4; pos = portPos = ipv4Pos;}
625  else if (isDNS)
626  {outAddr = dnsName; pos = portPos = dnsPos;}
627 
628  // Check for optional port number
629  char ch (CharAt(portPos));
630  if (ch != ':')
631  return true;
632  ++portPos;
633  if (!ParseDecNumber(portPos, port))
634  {pos = portPos; return false;} // Bad port number!
635  outPort = port;
636  pos = portPos;
637  return true;
638 }
639 
640 bool NTV2DeviceSpecParser::ParseResourcePath (size_t & pos, string & outRsrc)
641 {
642  outRsrc.clear();
643  string rsrc, name;
644  size_t rsrcPos(pos);
645  char ch(CharAt(rsrcPos));
646  while (ch == '/')
647  {
648  ++rsrcPos;
649  rsrc += '/';
650  if (!ParseAlphaNumeric(rsrcPos, name))
651  break;
652  rsrc += name;
653  ch = CharAt(rsrcPos);
654  }
655  if (!rsrc.empty())
656  pos = rsrcPos;
657  outRsrc = rsrc;
658  return !outRsrc.empty();
659 }
660 
661 bool NTV2DeviceSpecParser::ParseParamAssignment (size_t & pos, string & outKey, string & outValue)
662 {
663  outKey.clear(); outValue.clear();
664  string key, value;
665  size_t paramPos(pos);
666  char ch(CharAt(paramPos));
667  if (ch == '&')
668  ch = CharAt(++paramPos);
669  do
670  {
671  if (!ParseAlphaNumeric(paramPos, key))
672  break;
673  ch = CharAt(paramPos);
674  if (ch != '=')
675  break;
676  ch = CharAt(++paramPos);
677  while (ch != 0 && ch != '&')
678  {
679  value += ch;
680  ch = CharAt(++paramPos);
681  }
682  } while (false);
683  if (!key.empty())
684  {pos = paramPos; outKey = key; outValue = value;}
685  return !key.empty();
686 }
687 
688 bool NTV2DeviceSpecParser::ParseQuery (size_t & pos, NTV2Dictionary & outParams)
689 {
690  outParams.clear();
691  string key, value;
692  size_t queryPos(pos);
693  char ch(CharAt(queryPos));
694  if (ch != '?')
695  return false;
696  queryPos++;
697 
698  while (ParseParamAssignment(queryPos, key, value))
699  {
700  outParams.insert(key, value);
701  ch = CharAt(queryPos);
702  if (ch != '&')
703  break;
704  }
705  if (!outParams.empty())
706  pos = queryPos;
707  return !outParams.empty();
708 }
709 
710 bool NTV2DeviceSpecParser::IsSupportedScheme (const string & inScheme)
711 {
712  return inScheme.find("ntv2") == 0; // Starts with "ntv2"
713 }
714 
715 bool NTV2DeviceSpecParser::IsUpperLetter (const char inChar)
716 { static const string sHexDigits("_ABCDEFGHIJKLMNOPQRSTUVWXYZ");
717  return sHexDigits.find(inChar) != string::npos;
718 }
719 
720 bool NTV2DeviceSpecParser::IsLowerLetter (const char inChar)
721 { static const string sHexDigits("abcdefghijklmnopqrstuvwxyz");
722  return sHexDigits.find(inChar) != string::npos;
723 }
724 
725 bool NTV2DeviceSpecParser::IsLetter (const char inChar, const bool inIncludeUnderscore)
726 { return (inIncludeUnderscore && inChar == '_') || IsUpperLetter(inChar) || IsLowerLetter(inChar);
727 }
728 
729 bool NTV2DeviceSpecParser::IsDecimalDigit (const char inChar)
730 { static const string sDecDigits("0123456789");
731  return sDecDigits.find(inChar) != string::npos;
732 }
733 
734 bool NTV2DeviceSpecParser::IsHexDigit (const char inChar)
735 { static const string sHexDigits("0123456789ABCDEFabcdef");
736  return sHexDigits.find(inChar) != string::npos;
737 }
738 
739 bool NTV2DeviceSpecParser::IsLegalSerialNumChar (const char inChar)
740 { return IsLetter(inChar) || IsDecimalDigit(inChar);
741 }
742 
743 #if defined(_DEBUG)
744  void NTV2DeviceSpecParser::test (void)
745  {
746  NTV2DeviceSpecParser specParser;
747  specParser.Reset("1");
748  specParser.Reset("00000000000000000000000000000000000000000000000000000000000000000000000000000000000001");
749  specParser.Reset("corvid24");
750  specParser.Reset("corvid88");
751  specParser.Reset("konalhi");
752  specParser.Reset("alpha");
753  specParser.Reset("00T64450");
754  specParser.Reset("00t6-450");
755  specParser.Reset("BLATZBE0");
756  specParser.Reset("0x424C41545A424530");
757  specParser.Reset("0x424C415425424530");
758 
759  specParser.Reset("badscheme://1");
760 
761  specParser.Reset("ntv2local://1");
762  specParser.Reset("NtV2lOcAl://00000000000000000000000000000000000000000000000000000000000000000000000000000000000001");
763  specParser.Reset("NTV2Local://corvid24");
764  specParser.Reset("ntv2local://corvid88");
765  specParser.Reset("ntv2local://konalhi");
766  specParser.Reset("ntv2local://alpha");
767  specParser.Reset("ntv2local://00T64450");
768  specParser.Reset("ntv2local://00t6-450");
769  specParser.Reset("ntv2local://BLATZBE0");
770 
771  specParser.Reset("ntv2nub://1.2.3.4");
772  specParser.Reset("ntv2nub://1.2.3.4/doc");
773  specParser.Reset("ntv2nub://1.2.3.4/doc/");
774  specParser.Reset("ntv2nub://1.2.3.4/doc/alpha?one&two=2&three=&four=4");
775  specParser.Reset("ntv2nub://1.2.3.4/doc/?one&two=2&three=&four=4");
776  specParser.Reset("ntv2nub://1.2.3.4:badport/doc?one&two=2&three=&four=4");
777  specParser.Reset("ntv2nub://1.2.3.4:200/doc?one&two=2&three=&four=4");
778  specParser.Reset("ntv2nub://1.2.3.4:200/doc/?one&two=2&three=&four=4");
779  specParser.Reset("ntv2nub://1.2.3.4:12345");
780  specParser.Reset("ntv2nub://1.2.3.4:65000/doc");
781  specParser.Reset("ntv2nub://1.2.3.4:32767/doc/");
782  specParser.Reset("ntv2nub://1.2.3.4/path/to/doc/");
783  specParser.Reset("ntv2nub://1.2.3.4/path/to/doc/?");
784  specParser.Reset("ntv2nub://1.2.3.4/path/to/doc?");
785  specParser.Reset("ntv2nub://1.2.3.4/path/to/doc/?one");
786  specParser.Reset("ntv2nub://1.2.3.4/path/to/doc?one");
787  specParser.Reset("ntv2nub://1.2.3.4/path/to/doc/?one=");
788  specParser.Reset("ntv2nub://1.2.3.4/path/to/doc?one=");
789  specParser.Reset("ntv2nub://1.2.3.4/path/to/doc/?one=1");
790  specParser.Reset("ntv2nub://1.2.3.4/path/to/doc?one=1");
791  specParser.Reset("ntv2nub://1.2.3.4/path/to/doc/?one=1&two");
792  specParser.Reset("ntv2nub://1.2.3.4/path/to/doc?one=1&two");
793  specParser.Reset("ntv2nub://50.200.250.300");
794  specParser.Reset("ntv2nub://fully.qualified.domain.name.com/path/to/doc/?one=1&two");
795  specParser.Reset("ntv2nub://fully.qualified.domain.name.edu:badport/path/to/doc/?one=1&two");
796  specParser.Reset("ntv2nub://fully.qualified.domain.name.info:5544/path/to/doc/?one=1&two");
797  specParser.Reset("ntv2nub://fully.qualified.domain.name.org/path/to/doc/?one=1&two");
798  specParser.Reset("ntv2nub://fully.qualified.domain.name.nz:badport/path/to/doc/?one=1&two");
799  specParser.Reset("ntv2nub://fully.qualified.domain.name.au:000004/path/to/doc/?one=1&two");
800  specParser.Reset("ntv2nub://fully.qualified.domain.name.ch:4/corvid88");
801  specParser.Reset("ntv2nub://fully.qualified.domain.name.cn:4/00T64450");
802  specParser.Reset("ntv2nub://fully.qualified.domain.name.ru:4/2");
803  specParser.Reset("ntv2nub://fully.qualified.domain.name.co.uk:4/00000000000000000000000000000001");
804  specParser.Reset("ntv2nub://fully.qualified.domain.name.com:4/0000000000000000000000000000000001");
805  specParser.Reset("ntv2://swdevice/?"
806  "nosharedmemory"
807  "&supportlog=file%3A%2F%2F%2FUsers%2Fdemo%2FDesktop%2FAJAWatcherSupport.log"
808  "&sdram=file%3A%2F%2F%2FUsers%2Fdemo%2FDesktop%2FSDRAMsnapshot.dat");
809  }
810 #endif // defined(_DEBUG)
811 
812 #if defined(MSWindows)
813  static string WinErrStr (const DWORD inErr)
814  {
815  string result("foo");
816  LPVOID lpMsgBuf;
817  const DWORD res(FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER
818  | FORMAT_MESSAGE_FROM_SYSTEM
819  | FORMAT_MESSAGE_IGNORE_INSERTS, // dwFlags
820  AJA_NULL, // lpSource: n/a
821  inErr, // dwMessageId: n/a
822  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // dwLanguageId
823  (LPTSTR) &lpMsgBuf, // output buffer
824  0, // output buffer size, in TCHARs
825  AJA_NULL)); // user params
826  if (lpMsgBuf)
827  {
828  result = reinterpret_cast<const char *>(lpMsgBuf);
829  LocalFree(lpMsgBuf);
830  }
831  return result;
832  }
833 #endif // MSWindows
834 
835 
836 /*****************************************************************************************************************************************************
837  NTV2RPCClientAPI
838 *****************************************************************************************************************************************************/
840  : mConnectParams (inParams)
841 {
842  AJADebug::Open();
843 }
844 
846 {
847  if (IsConnected())
848  NTV2Disconnect();
849 }
850 
851 bool NTV2RPCClientAPI::SetConnectParams (const NTV2ConnectParams & inNewParams, const bool inAugment)
852 {
853  if (IsConnected())
854  {NBFAIL("Cannot set connect params while connected"); return false;}
855  size_t oldCount(mConnectParams.size()), updated(0), added(0);
856  if (inAugment)
857  {
858  updated = mConnectParams.UpdateFrom(inNewParams);
859  added = mConnectParams.AddFrom(inNewParams);
860  NBDBG(DEC(updated) << " connect param(s) updated, " << DEC(added) << " added: " << mConnectParams);
861  }
862  else
863  {
864  mConnectParams = inNewParams;
865  NBDBG(DEC(oldCount) << " connect param(s) removed, replaced with " << inNewParams);
866  }
867  if (mConnectParams.empty())
868  NBWARN("No connect params");
869  return true;
870 }
871 
872 ostream & NTV2RPCClientAPI::Print (ostream & oss) const
873 {
874  oss << (IsConnected() ? "Connected" : "Disconnected");
875  if (IsConnected() && !Name().empty())
876  oss << " to '" << Name() << "'";
877  return oss;
878 }
879 
880 string NTV2RPCClientAPI::Description (void) const
881 {
882  return "";
883 }
884 
886 {
887  if (IsConnected())
888  NTV2Disconnect();
889  return NTV2OpenRemote();
890 }
891 
893 {
894  return NTV2CloseRemote();
895 }
896 
897 bool NTV2RPCClientAPI::NTV2ReadRegisterRemote (const ULWord regNum, ULWord & outRegValue, const ULWord regMask, const ULWord regShift)
898 { (void) regNum; (void) outRegValue; (void) regMask; (void) regShift;
899  return false; // UNIMPLEMENTED
900 }
901 
902 bool NTV2RPCClientAPI::NTV2WriteRegisterRemote (const ULWord regNum, const ULWord regValue, const ULWord regMask, const ULWord regShift)
903 { (void) regNum; (void) regValue; (void) regMask; (void) regShift;
904  return false; // UNIMPLEMENTED
905 }
906 
908 { (void) autoCircData;
909  return false; // UNIMPLEMENTED
910 }
911 
913 { (void) eInterrupt; (void) timeOutMs;
914  return false; // UNIMPLEMENTED
915 }
916 
917 #if !defined(NTV2_DEPRECATE_16_3)
919  { (void) bitFileType;
920  ::memset(&bitFileInfo, 0, sizeof(bitFileInfo));
921  return false; // UNIMPLEMENTED
922  }
923 
925  {
926  ::memset(&buildInfo, 0, sizeof(buildInfo));
927  return false; // UNIMPLEMENTED
928  }
929 
931  const UWord signalMask, const bool testPatDMAEnb, const ULWord testPatNum)
932  { (void) channel; (void) testPatternFBF; (void) signalMask; (void) testPatDMAEnb; (void) testPatNum;
933  return false; // UNIMPLEMENTED
934  }
935 
936  bool NTV2RPCClientAPI::NTV2ReadRegisterMultiRemote (const ULWord numRegs, ULWord & outFailedRegNum, NTV2RegInfo outRegs[])
937  { (void) numRegs; (void) outFailedRegNum; (void) outRegs;
938  return false; // UNIMPLEMENTED
939  }
940 
942  {
943  outDriverVersion = 0xFFFFFFFF;
944  return false; // UNIMPLEMENTED
945  }
946 #endif // !defined(NTV2_DEPRECATE_16_3)
947 
948 bool NTV2RPCClientAPI::NTV2DMATransferRemote ( const NTV2DMAEngine inDMAEngine, const bool inIsRead, const ULWord inFrameNumber,
949  NTV2Buffer & inOutFrameBuffer, const ULWord inCardOffsetBytes,
950  const ULWord inNumSegments, const ULWord inSegmentHostPitch,
951  const ULWord inSegmentCardPitch, const bool inSynchronous)
952 { (void) inDMAEngine; (void) inIsRead; (void) inFrameNumber; (void) inOutFrameBuffer;
953  (void) inCardOffsetBytes; (void) inNumSegments; (void) inSegmentHostPitch;
954  (void) inSegmentCardPitch; (void) inSynchronous;
955  return false; // UNIMPLEMENTED
956 }
957 
959 { (void) pInMessage;
960  return false; // UNIMPLEMENTED
961 }
962 
963 bool NTV2RPCClientAPI::NTV2GetBoolParamRemote (const ULWord inParamID, ULWord & outValue)
964 { (void) inParamID;
965  outValue = 0;
966  return false; // UNIMPLEMENTED
967 }
968 
970 { (void) inParamID;
971  outValue = 0;
972  return false; // UNIMPLEMENTED
973 }
974 
975 bool NTV2RPCClientAPI::NTV2GetSupportedRemote (const ULWord inEnumsID, ULWordSet & outSupported)
976 { (void) inEnumsID;
977  outSupported.clear();
978  return false; // UNIMPLEMENTED
979 }
980 
982 {
983  return false; // UNIMPLEMENTED
984 }
985 
987 {
988  mConnectParams.clear();
989  return true;
990 }
991 
992 
993 // Loads NTV2 plugin, and returns address of given function
994 static uint64_t * GetNTV2PluginFunction (const NTV2ConnectParams & inParams, const string & inFuncName)
995 {
996  // Scheme dictates which plugin to load...
997  if (!inParams.hasKey(kConnectParamScheme))
998  {NBCFAIL("Missing scheme -- params: " << inParams); return AJA_NULL;} // No scheme
999  string scheme(inParams.valueForKey(kConnectParamScheme));
1000  if (scheme.find("ntv2")) // scheme must start with "ntv2"
1001  {NBCFAIL("Scheme '" << inParams.valueForKey(kConnectParamScheme) << "' results in empty plugin name"); return AJA_NULL;} // No "host"
1002  scheme.erase(0,4); // Remainder of scheme yields DLL/dylib/so name...
1003 
1004  // Look for plugins in the "AJA" folder (usually parent folder of our "firmware" folder)...
1005  string pluginName(scheme), pluginPath, dllsFolder, errStr;
1007  if (AJA_FAILURE(sysInfo.GetValue(AJA_SystemInfoTag_Path_Firmware, pluginPath)))
1008  {NBCFAIL("AJA_SystemInfoTag_Path_Firmware failed"); return AJA_NULL;} // Can't get firmware folder
1009  NBCDBG("AJA firmware path is '" << pluginPath << "', seeking '" << pluginName << DLL_EXTENSION "'");
1010  // Lop off trailing "Firmware/"...
1011  if (pluginPath.find(FIRMWARE_FOLDER) == string::npos)
1012  {NBSFAIL("'" << pluginPath << "' doesn't end with '" << FIRMWARE_FOLDER << "'"); return AJA_NULL;}
1013  pluginPath.erase(pluginPath.find(FIRMWARE_FOLDER), 9); // Lop off trailing "Firmware/"
1014  dllsFolder = pluginPath;
1015  dllsFolder.erase(dllsFolder.length()-1,1); // Lop off trailing slash or backslash
1016  pluginPath += pluginName + DLL_EXTENSION; // Append plugin name + extension...
1017 
1018  ostringstream err;
1019  #if defined(MSWindows)
1020  // Open the DLL (Windows)...
1021  std::wstring dllsFolderW;
1022  aja::string_to_wstring(dllsFolder, dllsFolderW);
1023  if (!AddDllDirectory(dllsFolderW.c_str()))
1024  { NBCFAIL("AddDllDirectory '" << pluginPath << "' failed: " << WinErrStr(::GetLastError()));
1025  return AJA_NULL;
1026  } // AddDllDirectory failed
1027  HMODULE pHandle = ::LoadLibraryExA(LPCSTR(pluginPath.c_str()), AJA_NULL, LOAD_LIBRARY_SEARCH_USER_DIRS);
1028  if (!pHandle)
1029  err << "Unable to open '" << pluginPath << "' in '" << dllsFolder << "': " << WinErrStr(::GetLastError());
1030  #elif defined(AJABareMetal)
1031  // TODO
1032  void *pHandle = AJA_NULL;
1033  uint64_t *pFunc = AJA_NULL;
1034  #else // MacOS or Linux
1035  // Open the .dylib (MacOS) or .so (Linux)...
1036  void* pHandle = ::dlopen(pluginPath.c_str(), RTLD_LAZY);
1037  if (!pHandle)
1038  { const char * pErrorStr(::dlerror());
1039  errStr = pErrorStr ? pErrorStr : "";
1040  err << "Unable to open '" << pluginPath << "': " << errStr;
1041  } // dlopen failed
1042  #endif // MacOS or Linux
1043  if (!pHandle)
1044  {NBCFAIL(err.str()); return AJA_NULL;}
1045  NBCDBG("'" << pluginPath << "' opened");
1046 
1047  // Get pointer to its CreateClient function...
1048  #if defined(MSWindows)
1049  uint64_t * pFunc = reinterpret_cast<uint64_t*>(::GetProcAddress(pHandle, inFuncName.c_str()));
1050  if (!pFunc)
1051  err << "'GetProcAddress' failed for '" << inFuncName << "' in '" << pluginPath << "': " << WinErrStr(::GetLastError());
1052  #elif defined(AJABareMetal)
1053  // TODO
1054  #else // MacOS or Linux
1055  uint64_t * pFunc = reinterpret_cast<uint64_t*>(::dlsym(pHandle, inFuncName.c_str()));
1056  if (!pFunc)
1057  { const char * pErrorStr(::dlerror());
1058  errStr = pErrorStr ? pErrorStr : "";
1059  err << "'dlsym' failed for '" << inFuncName << "' in '" << pluginPath << "': " << errStr;
1060  }
1061  #endif // MacOS or Linux
1062  if (!pFunc)
1063  {
1064  NBCFAIL(err.str());
1065  #if defined(AJABareMetal)
1066  // TODO
1067  #elif !defined(MSWindows)
1068  ::dlclose(pHandle);
1069  #else // MSWindows
1070  ::FreeLibrary(pHandle);
1071  #endif // MSWindows
1072  }
1073  else NBCDBG("Calling '" << inFuncName << "' in '" << pluginPath << "'");
1074  return pFunc;
1075 } // GetNTV2PluginFunction
1076 
1077 
1079 {
1080  const string funcName(kFuncNameCreateClient);
1081  uint64_t * pFunc = GetNTV2PluginFunction(inParams, funcName);
1082  fpCreateClient pCreateFunc = reinterpret_cast<fpCreateClient>(pFunc);
1083  if (!pCreateFunc)
1084  return AJA_NULL;
1085 
1086  // Call its Create function to instantiate the NTV2RPCClientAPI object...
1087  NTV2RPCClientAPI * pRPCObject = (*pCreateFunc) (AJA_NULL, inParams, AJA_NTV2_SDK_VERSION);
1088  if (!pRPCObject)
1089  NBCFAIL("'" << funcName << "' failed to return NTV2RPCClientAPI instance using: " << inParams);
1090  else
1091  NBCINFO("'" << funcName << "' created instance " << xHEX0N(uint64_t(pRPCObject),16));
1092  return pRPCObject;
1093 } // CreateClient
1094 
1095 
1096 /*****************************************************************************************************************************************************
1097  NTV2RPCServerAPI
1098 *****************************************************************************************************************************************************/
1099 
1101 {
1102  const string funcName(kFuncNameCreateServer);
1103  uint64_t * pFunc = GetNTV2PluginFunction(inParams, funcName);
1104  fpCreateServer pCreateFunc = reinterpret_cast<fpCreateServer>(pFunc);
1105  if (!pCreateFunc)
1106  return AJA_NULL;
1107 
1108  // Call its Create function to instantiate the NTV2RPCServerAPI object...
1109  NTV2RPCServerAPI * pRPCObject = (*pCreateFunc) (AJA_NULL, inParams, AJA_NTV2_SDK_VERSION);
1110  if (!pRPCObject)
1111  NBSFAIL("'" << funcName << "' failed to return NTV2RPCServerAPI instance using: " << inParams);
1112  else
1113  NBSINFO("'" << funcName << "' created instance " << xHEX0N(uint64_t(pRPCObject),16));
1114  return pRPCObject; // It's caller's responsibility to delete pRPCObject
1115 
1116 } // CreateServer
1117 
1118 NTV2RPCServerAPI * NTV2RPCServerAPI::CreateServer (const string & inURL) // CLASS METHOD
1119 {
1120  NTV2DeviceSpecParser parser(inURL);
1121  if (parser.HasErrors())
1122  return AJA_NULL;
1123  return CreateServer(parser.Results());
1124 }
1125 
1127  : mConfigParams (inParams)
1128 {
1129  NTV2Buffer spare(&mSpare, sizeof(mSpare)); spare.Fill(0ULL);
1130  AJADebug::Open();
1131 }
1132 
1134 {
1135 }
1136 
1138 { // This function normally should never be called;
1139  // It's usually overridden by a subclass
1140  NBSDBG("Started");
1141  while (!mSpare[0])
1142  AJATime::Sleep(500);
1143  NBSDBG("Terminated");
1144 } // ServerFunction
1145 
1146 ostream & NTV2RPCServerAPI::Print (ostream & oss) const
1147 {
1148  oss << mConfigParams;
1149  return oss;
1150 }
1151 
1152 bool NTV2RPCServerAPI::SetConfigParams (const NTV2ConnectParams & inNewParams, const bool inAugment)
1153 {
1154  size_t oldCount(mConfigParams.size()), updated(0), added(0);
1155  if (inAugment)
1156  {
1157  updated = mConfigParams.UpdateFrom(inNewParams);
1158  added = mConfigParams.AddFrom(inNewParams);
1159  NBSDBG(DEC(updated) << " config param(s) updated, " << DEC(added) << " added: " << mConfigParams);
1160  }
1161  else
1162  {
1163  mConfigParams = inNewParams;
1164  NBSDBG(DEC(oldCount) << " config param(s) removed, replaced with " << inNewParams);
1165  }
1166  if (mConfigParams.empty())
1167  NBSWARN("No config params");
1168  return true;
1169 }
AJA_SystemInfoSection_Path
@ AJA_SystemInfoSection_Path
Definition: info.h:61
NTV2RPCClientAPI::NTV2WriteRegisterRemote
virtual bool NTV2WriteRegisterRemote(const ULWord regNum, const ULWord regValue, const ULWord regMask, const ULWord regShift)
Definition: ntv2nubaccess.cpp:902
NTV2RPCClientAPI::NTV2GetNumericParamRemote
virtual bool NTV2GetNumericParamRemote(const ULWord inParamID, ULWord &outValue)
Definition: ntv2nubaccess.cpp:969
aja::stoul
unsigned long stoul(const std::string &str, std::size_t *idx, int base)
Definition: common.cpp:143
NTV2DeviceSpecParser::Reset
void Reset(const std::string inSpec="")
Resets me, then parses the given device specification.
Definition: ntv2nubaccess.cpp:175
DLL_EXTENSION
#define DLL_EXTENSION
Definition: ntv2nubaccess.cpp:20
info.h
Declares the AJASystemInfo class.
NTV2RPCClientAPI::NTV2OpenRemote
virtual bool NTV2OpenRemote(void)
Definition: ntv2nubaccess.cpp:981
NTV2RPCServerAPI::NTV2RPCServerAPI
NTV2RPCServerAPI(const NTV2ConnectParams &inParams)
My constructor.
Definition: ntv2nubaccess.cpp:1126
INTERRUPT_ENUMS
enum _INTERRUPT_ENUMS_ INTERRUPT_ENUMS
BUILD_INFO_STRUCT
Definition: ntv2publicinterface.h:4887
AJA_SystemInfoMemoryUnit_Megabytes
@ AJA_SystemInfoMemoryUnit_Megabytes
Definition: info.h:23
NTV2RPCClientAPI::NTV2Disconnect
virtual bool NTV2Disconnect(void)
Disconnects me from the remote/fake host, closing the connection.
Definition: ntv2nubaccess.cpp:892
NTV2StringSet
std::set< std::string > NTV2StringSet
Definition: ntv2utils.h:1137
NTV2RPCClientAPI::NTV2DriverGetBitFileInformationRemote
virtual bool NTV2DriverGetBitFileInformationRemote(BITFILE_INFO_STRUCT &bitFileInfo, const NTV2BitFileType bitFileType)
Definition: ntv2nubaccess.cpp:918
NTV2GetSupportedDevices
NTV2DeviceIDSet NTV2GetSupportedDevices(const NTV2DeviceKinds inKinds=NTV2_DEVICEKIND_ALL)
Returns an NTV2DeviceIDSet of devices supported by the SDK.
Definition: ntv2utils.cpp:7552
kConnectParamResource
static const std::string kConnectParamResource("ResourcePath")
Resource path – everything past URL [scheme://host[:port]/], excluding [?query].
NTV2Channel
NTV2Channel
These enum values are mostly used to identify a specific Frame Store. They're also commonly used to i...
Definition: ntv2enums.h:1305
NTV2Buffer
A generic user-space buffer object that has an address and a length. Used most often to share an arbi...
Definition: ntv2publicinterface.h:5967
AJA_SystemInfoTag_Path_Firmware
@ AJA_SystemInfoTag_Path_Firmware
Definition: info.h:50
fpCreateClient
NTV2RPCClientAPI *(* fpCreateClient)(void *, const NTV2ConnectParams &, const uint32_t)
Instantiates a new client instance to talk to a remote server.
Definition: ntv2nubaccess.h:353
fpCreateServer
NTV2RPCServerAPI *(* fpCreateServer)(void *, const NTV2ConfigParams &, const uint32_t)
Instantiates a new server instance for talking to clients.
Definition: ntv2nubaccess.h:363
kConnectParamDevModel
static const std::string kConnectParamDevModel("DeviceModel")
First device of this model (e.g. 'kona4')
systemtime.h
Declares the AJATime class.
NTV2RPCServerAPI
Base class of objects that can serve device operation RPCs with NTV2RPCClientAPI instances.
Definition: ntv2nubaccess.h:281
NTV2RPCClientAPI::~NTV2RPCClientAPI
virtual ~NTV2RPCClientAPI()
My destructor, automatically calls NTV2Disconnect.
Definition: ntv2nubaccess.cpp:845
NTV2RPCClientAPI::NTV2DMATransferRemote
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)
Definition: ntv2nubaccess.cpp:948
NBSINFO
#define NBSINFO(__x__)
Definition: ntv2nubaccess.cpp:50
NTV2DeviceID
NTV2DeviceID
Identifies a specific AJA NTV2 device model number. The NTV2DeviceID is actually the PROM part number...
Definition: ntv2enums.h:20
NTV2DeviceSpecParser::DeviceID
NTV2DeviceID DeviceID(void) const
Definition: ntv2nubaccess.cpp:369
NTV2FrameBufferFormat
NTV2FrameBufferFormat
Identifies a particular video frame buffer format. See Device Frame Buffer Formats for details.
Definition: ntv2enums.h:207
NTV2Dictionary::Print
std::ostream & Print(std::ostream &oss, const bool inCompact=true) const
Prints human-readable representation to ostream.
Definition: ntv2nubaccess.cpp:98
NBSFAIL
#define NBSFAIL(__x__)
Definition: ntv2nubaccess.cpp:47
NBFAIL
#define NBFAIL(__x__)
Definition: ntv2nubaccess.cpp:37
NTV2DeviceIDSetConstIter
NTV2DeviceIDSet::const_iterator NTV2DeviceIDSetConstIter
A convenient const iterator for NTV2DeviceIDSet.
Definition: ntv2utils.h:1033
NTV2RPCClientAPI::mConnectParams
NTV2ConnectParams mConnectParams
Copy of connection parameters passed in to NTV2Connect.
Definition: ntv2nubaccess.h:269
kConnectParamDevID
static const std::string kConnectParamDevID("DeviceID")
First device having this ID (e.g. '0x10518400')
NTV2RPCClientAPI::NTV2GetDriverVersionRemote
virtual bool NTV2GetDriverVersionRemote(ULWord &outDriverVersion)
Definition: ntv2nubaccess.cpp:941
ajatypes.h
Declares the most fundamental data types used by NTV2. Since Windows NT was the first principal devel...
GetNTV2PluginFunction
static uint64_t * GetNTV2PluginFunction(const NTV2ConnectParams &inParams, const string &inFuncName)
Definition: ntv2nubaccess.cpp:994
NTV2DeviceSpecParser::Print
std::ostream & Print(std::ostream &oss, const bool inDumpResults=false) const
Definition: ntv2nubaccess.cpp:331
NTV2RPCClientAPI::NTV2CloseRemote
virtual bool NTV2CloseRemote(void)
Definition: ntv2nubaccess.cpp:986
NTV2DeviceSpecParser::Resource
std::string Resource(const bool inStripLeadSlash=true) const
Definition: ntv2nubaccess.cpp:186
NBCFAIL
#define NBCFAIL(__x__)
Definition: ntv2nubaccess.cpp:42
NTV2RPCServerAPI::mSpare
uint32_t mSpare[1024]
Reserved.
Definition: ntv2nubaccess.h:334
NTV2DMAEngine
NTV2DMAEngine
Definition: ntv2enums.h:1801
aja::lower
std::string & lower(std::string &str)
Definition: common.cpp:436
NBCDBG
#define NBCDBG(__x__)
Definition: ntv2nubaccess.cpp:46
NBWARN
#define NBWARN(__x__)
Definition: ntv2nubaccess.cpp:38
AJATime::Sleep
static void Sleep(const int32_t inMilliseconds)
Suspends execution of the current thread for a given number of milliseconds.
Definition: systemtime.cpp:284
kConnectParamDevIndex
static const std::string kConnectParamDevIndex("DeviceIndex")
Device having this index number.
ULWordSet
std::set< ULWord > ULWordSet
A collection of unique ULWord (uint32_t) values.
Definition: ntv2publicinterface.h:53
AJASystemInfo::GetValue
virtual AJAStatus GetValue(const AJASystemInfoTag inTag, std::string &outValue) const
Answers with the host system info value string for the given AJASystemInfoTag.
Definition: info.cpp:151
ULWord
uint32_t ULWord
Definition: ajatypes.h:246
NTV2BitFileType
NTV2BitFileType
Definition: ntv2enums.h:3269
NTV2RPCClientAPI::NTV2GetBoolParamRemote
virtual bool NTV2GetBoolParamRemote(const ULWord inParamID, ULWord &outValue)
Definition: ntv2nubaccess.cpp:963
NTV2RPCClientAPI::NTV2RPCClientAPI
NTV2RPCClientAPI(const NTV2ConnectParams &inParams)
My constructor.
Definition: ntv2nubaccess.cpp:839
NTV2RPCServerAPI::Print
virtual std::ostream & Print(std::ostream &oss) const
Definition: ntv2nubaccess.cpp:1146
NTV2DeviceIDToString
std::string NTV2DeviceIDToString(const NTV2DeviceID inValue, const bool inForRetailDisplay=false)
Definition: ntv2utils.cpp:4673
NTV2RPCClientAPI::NTV2DriverGetBuildInformationRemote
virtual bool NTV2DriverGetBuildInformationRemote(BUILD_INFO_STRUCT &buildInfo)
Definition: ntv2nubaccess.cpp:924
NBDBG
#define NBDBG(__x__)
Definition: ntv2nubaccess.cpp:41
NTV2RPCClientAPI::SetConnectParams
virtual bool SetConnectParams(const NTV2ConnectParams &inNewParams, const bool inAugment=false)
Replaces or adds to my connect parameters.
Definition: ntv2nubaccess.cpp:851
kConnectParamHost
static const std::string kConnectParamHost("Host")
DNS name, IPv4 or sw device DLL name.
NTV2RPCClientAPI::Description
virtual std::string Description(void) const
Definition: ntv2nubaccess.cpp:880
StringToSerialNum64
bool StringToSerialNum64(const std::string &inSerNumStr, uint64_t &outSerNum)
NTV2_HEADER
All new NTV2 structs start with this common header.
Definition: ntv2publicinterface.h:6899
NBCINFO
#define NBCINFO(__x__)
Definition: ntv2nubaccess.cpp:45
kConnectParamQuery
static const std::string kConnectParamQuery("Query")
Query – everything past '?' in URL.
aja::upper
std::string & upper(std::string &str)
Definition: common.cpp:442
UWord
uint16_t UWord
Definition: ajatypes.h:244
NTV2RPCServerAPI::~NTV2RPCServerAPI
virtual ~NTV2RPCServerAPI()
My destructor, automatically calls NTV2Disconnect.
Definition: ntv2nubaccess.cpp:1133
kFuncNameCreateServer
static const std::string kFuncNameCreateServer("CreateServer")
Create an NTV2RPCServerAPI instance.
NTV2DeviceSpecParser::NTV2DeviceSpecParser
NTV2DeviceSpecParser(const std::string inSpec="")
My constructor. If given device specification is non-empty, proceeds to Parse it.
Definition: ntv2nubaccess.cpp:170
aja::string_to_wstring
bool string_to_wstring(const std::string &str, std::wstring &wstr)
Definition: common.cpp:248
ntv2utils.h
Declares numerous NTV2 utility functions.
kConnectParamDevSerial
static const std::string kConnectParamDevSerial("DeviceSerial")
Device with this serial number.
NTV2RPCClientAPI::NTV2DownloadTestPatternRemote
virtual bool NTV2DownloadTestPatternRemote(const NTV2Channel channel, const NTV2PixelFormat testPatternFBF, const UWord signalMask, const bool testPatDMAEnb, const ULWord testPatNum)
Definition: ntv2nubaccess.cpp:930
NTV2DeviceSpecParser::DeviceIndex
UWord DeviceIndex(void) const
Definition: ntv2nubaccess.cpp:378
NTV2DeviceSpecParser::IsSupportedScheme
static bool IsSupportedScheme(const std::string &inScheme)
Definition: ntv2nubaccess.cpp:710
AJA_NTV2_SDK_VERSION
#define AJA_NTV2_SDK_VERSION
Definition: ntv2version.h:20
NTV2RPCServerAPI::mConfigParams
NTV2ConfigParams mConfigParams
Copy of config params passed in to my constructor.
Definition: ntv2nubaccess.h:333
aja::stoull
unsigned long long stoull(const std::string &str, std::size_t *idx, int base)
Definition: common.cpp:154
ntv2version.h
Defines for the NTV2 SDK version number, used by ajantv2/includes/ntv2enums.h. See the ajantv2/includ...
NTV2Dictionary::DictConstIter
Dict::const_iterator DictConstIter
Definition: ntv2nubaccess.h:75
NTV2Dictionary::u16ValueForKey
uint16_t u16ValueForKey(const std::string &inKey, const uint16_t inDefault=0) const
Definition: ntv2nubaccess.cpp:62
kFuncNameCreateClient
static const std::string kFuncNameCreateClient("CreateClient")
Create an NTV2RPCClientAPI instance.
NTV2DeviceSpecParser::DeviceSerial
uint64_t DeviceSerial(void) const
Definition: ntv2nubaccess.cpp:362
NTV2RPCClientAPI::CreateClient
static NTV2RPCClientAPI * CreateClient(const NTV2ConnectParams &inParams)
Definition: ntv2nubaccess.cpp:1078
AJADebug::Open
static AJAStatus Open(bool incrementRefCount=false)
Definition: debug.cpp:44
AJA_NULL
#define AJA_NULL
Definition: ajatypes.h:190
NTV2RPCClientAPI::NTV2AutoCirculateRemote
virtual bool NTV2AutoCirculateRemote(AUTOCIRCULATE_DATA &autoCircData)
Definition: ntv2nubaccess.cpp:907
NTV2RPCClientAPI::NTV2WaitForInterruptRemote
virtual bool NTV2WaitForInterruptRemote(const INTERRUPT_ENUMS eInterrupt, const ULWord timeOutMs)
Definition: ntv2nubaccess.cpp:912
NTV2DeviceSpecParser
One-stop shop for parsing device specifications. (New in SDK 16.3) I do very little in the way of val...
Definition: ntv2nubaccess.h:93
NTV2RPCServerAPI::RunServer
virtual void RunServer(void)
Principal server thread function, subclsses should override.
Definition: ntv2nubaccess.cpp:1137
NTV2Dictionary::AddFrom
size_t AddFrom(const NTV2Dictionary &inDict)
Adds all values from inDict with non-matching keys, ignoring all matching keys.
Definition: ntv2nubaccess.cpp:160
NTV2Dictionary::UpdateFrom
size_t UpdateFrom(const NTV2Dictionary &inDict)
Updates all values from inDict with matching keys, ignoring all non-matching keys.
Definition: ntv2nubaccess.cpp:151
DEC
#define DEC(__x__)
Definition: ntv2publicinterface.h:5579
common.h
Private include file for all ajabase sources.
NTV2RPCServerAPI::SetConfigParams
virtual bool SetConfigParams(const NTV2ConfigParams &inNewParams, const bool inAugment=false)
Replaces or adds to my config parameters.
Definition: ntv2nubaccess.cpp:1152
NTV2DeviceSpecParser::PrintErrors
std::ostream & PrintErrors(std::ostream &oss) const
Definition: ntv2nubaccess.cpp:385
ULWord64
uint64_t ULWord64
Definition: ajatypes.h:249
NBSWARN
#define NBSWARN(__x__)
Definition: ntv2nubaccess.cpp:48
NTV2RPCClientAPI::NTV2Connect
virtual bool NTV2Connect(void)
Definition: ntv2nubaccess.cpp:885
AJA_sERROR
#define AJA_sERROR(_index_, _expr_)
Definition: debug.h:176
AJA_DebugUnit_Application
@ AJA_DebugUnit_Application
Definition: debugshare.h:58
NTV2RPCClientAPI::NTV2GetSupportedRemote
virtual bool NTV2GetSupportedRemote(const ULWord inEnumsID, ULWordSet &outSupported)
Definition: ntv2nubaccess.cpp:975
NTV2DeviceIDSet
std::set< NTV2DeviceID > NTV2DeviceIDSet
A set of NTV2DeviceIDs.
Definition: ntv2utils.h:1031
NTV2RPCServerAPI::CreateServer
static NTV2RPCServerAPI * CreateServer(const NTV2ConfigParams &inParams)
Factory method that instantiates a new NTV2RPCServerAPI instance using a plugin based on the specifie...
Definition: ntv2nubaccess.cpp:1100
NTV2RPCClientAPI::NTV2MessageRemote
virtual bool NTV2MessageRemote(NTV2_HEADER *pInMessage)
Definition: ntv2nubaccess.cpp:958
NTV2Buffer::Fill
bool Fill(const T &inValue)
Fills me with the given scalar value.
Definition: ntv2publicinterface.h:6192
NTV2RPCClientAPI::NTV2ReadRegisterMultiRemote
virtual bool NTV2ReadRegisterMultiRemote(const ULWord numRegs, ULWord &outFailedRegNum, NTV2RegInfo outRegs[])
Definition: ntv2nubaccess.cpp:936
ntv2publicinterface.h
Declares enums and structs used by all platform drivers and the SDK.
kLegalSchemeNTV2Local
static const std::string kLegalSchemeNTV2Local("ntv2local")
NTV2Dictionary::largestKeySize
size_t largestKeySize(void) const
Definition: ntv2nubaccess.cpp:133
NTV2RPCClientAPI::Print
virtual std::ostream & Print(std::ostream &oss) const
Definition: ntv2nubaccess.cpp:872
FIRMWARE_FOLDER
#define FIRMWARE_FOLDER
Definition: ntv2nubaccess.cpp:21
xHEX0N
#define xHEX0N(__x__, __n__)
Definition: ntv2publicinterface.h:5578
AJA_FAILURE
#define AJA_FAILURE(_status_)
Definition: types.h:358
NTV2RPCClientAPI
Base class of objects that can connect to, and operate remote or fake devices. I have three general A...
Definition: ntv2nubaccess.h:176
kConnectParamScheme
static const std::string kConnectParamScheme("Scheme")
URL scheme.
NTV2Dictionary::valueForKey
std::string valueForKey(const std::string &inKey) const
Definition: ntv2nubaccess.cpp:54
kConnectParamPort
static const std::string kConnectParamPort("Port")
Port number (optional)
NTV2Dictionary::largestValueSize
size_t largestValueSize(void) const
Definition: ntv2nubaccess.cpp:142
NTV2Dictionary::keys
NTV2StringSet keys(void) const
Definition: ntv2nubaccess.cpp:125
NTV2Dictionary
A simple set of zero or more key/value pairs. (New in SDK 16.3)
Definition: ntv2nubaccess.h:44
NTV2DeviceSpecParser::InfoString
std::string InfoString(void) const
Definition: ntv2nubaccess.cpp:355
AJA_sDEBUG
#define AJA_sDEBUG(_index_, _expr_)
Definition: debug.h:220
BITFILE_INFO_STRUCT
Definition: ntv2publicinterface.h:4772
NTV2RPCClientAPI::NTV2ReadRegisterRemote
virtual bool NTV2ReadRegisterRemote(const ULWord regNum, ULWord &outRegValue, const ULWord regMask, const ULWord regShift)
Definition: ntv2nubaccess.cpp:897
ntv2nubaccess.h
Declares NTV2 "nub" client functions.
NTV2RegInfo
Everything needed to call CNTV2Card::ReadRegister or CNTV2Card::WriteRegister functions.
Definition: ntv2publicinterface.h:3900
debug.h
Declares the AJADebug class.
AUTOCIRCULATE_DATA
Definition: ntv2publicinterface.h:4338
NBSDBG
#define NBSDBG(__x__)
Definition: ntv2nubaccess.cpp:51
AJASystemInfo
Definition: info.h:78