AJA NTV2 SDK  17.5.0.1242
NTV2 SDK 17.5.0.1242
infoimpl.mm
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
9 #include "ajabase/system/info.h"
10 #include <sys/types.h>
11 #include <sys/sysctl.h>
12 #include <sys/utsname.h>
13 #include <mach/mach.h>
14 #import <Foundation/Foundation.h>
15 #include <Availability.h>
16 #include <sstream>
17 
18 static AJAStatus
19 aja_sysctl(const char *name, std::string &result)
20 {
22 
23  static char tmp_buf[4096];
24  size_t size = sizeof(tmp_buf);
25 
26  // special cases
27  if (strcmp(name, "kern.boottime") == 0)
28  {
29  // timeval variants
30 
31  timeval tv;
32  size = sizeof(tv);
33  if (sysctlbyname(name, (void *)&tv, &size, NULL, 0) == 0)
34  {
35  time_t t;
36  struct tm *tm;
37  t = tv.tv_sec;
38  tm = localtime(&t);
39  strftime(tmp_buf, sizeof(tmp_buf), "%Y-%m-%d %H:%M:%S", tm);
40 
41  result = tmp_buf;
42  ret = AJA_STATUS_SUCCESS;
43  }
44  }
45  else if (strcmp(name, "hw.memsize") == 0)
46  {
47  // int64_t variants
48 
49  int64_t v;
50  size = sizeof(v);
51  if (sysctlbyname(name, (void *)&v, &size, NULL, 0) == 0)
52  {
53  std::ostringstream oss;
54  oss << v;
55  result = oss.str();
56  ret = AJA_STATUS_SUCCESS;
57  }
58  }
59  else if (strcmp(name, "hw.logicalcpu") == 0)
60  {
61  // int32_t variants
62 
63  int32_t v;
64  size = sizeof(v);
65  if (sysctlbyname(name, (void *)&v, &size, NULL, 0) == 0)
66  {
67  std::ostringstream oss;
68  oss << v;
69  result = oss.str();
70  ret = AJA_STATUS_SUCCESS;
71  }
72  }
73  else if (strcmp(name, "aja.osversion") == 0)
74  {
75  // no sysctl for this, so fake it
76 
77 #if defined(__MAC_10_10) && __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_10
78  NSOperatingSystemVersion v = [[NSProcessInfo processInfo] operatingSystemVersion];
79  std::ostringstream oss;
80  oss << v.majorVersion << "." << v.minorVersion << "." << v.patchVersion;
81  result = oss.str();
82 #else
83  SInt32 majorVersion,minorVersion,pointVersion;
84  Gestalt(gestaltSystemVersionMajor, &majorVersion);
85  Gestalt(gestaltSystemVersionMinor, &minorVersion);
86  Gestalt(gestaltSystemVersionBugFix, &pointVersion);
87 
88  std::ostringstream oss;
89  oss << majorVersion << "." << minorVersion << "." << pointVersion;
90  result = oss.str();
91 #endif
92  ret = AJA_STATUS_SUCCESS;
93  }
94  else if (sysctlbyname(name, tmp_buf, &size, NULL, 0) == 0)
95  {
96  // string case
97 
98  result = tmp_buf;
99  ret = AJA_STATUS_SUCCESS;
100  }
101 
102  return ret;
103 }
104 
105 static CFDictionaryRef find_dict_for_data_type(const CFArrayRef inArray, CFStringRef inDataType)
106 {
107  for (CFIndex i = 0; i<CFArrayGetCount(inArray); i++)
108  {
109  CFDictionaryRef theDictionary = CFDictionaryRef(CFArrayGetValueAtIndex(inArray, i));
110 
111  // If the CFDictionary at this index has a key/value pair with the value equal to inDataType,
112  // retain and return it, caller is responsible for releasing it.
113  if (CFDictionaryContainsValue(theDictionary, inDataType))
114  {
115  CFRetain(theDictionary);
116  return theDictionary;
117  }
118  }
119  return NULL;
120 }
121 
122 static CFArrayRef get_items_array_from_dict(const CFDictionaryRef inDictionary)
123 {
124  CFArrayRef itemsArray = CFArrayRef(CFDictionaryGetValue(inDictionary, CFSTR("_items")));
125  if (itemsArray != NULL)
126  {
127  // retain and return it, caller is responsible for releasing it.
128  CFRetain(itemsArray);
129  }
130  return itemsArray;
131 }
132 
133 static std::string aja_getgputype(void)
134 {
135  std::ostringstream oss;
136 
137  // get the display information from system_profiler, in xml form
138  std::vector<char> streamBuffer(512*512);
139  FILE *sys_profile = popen("system_profiler SPDisplaysDataType -xml", "r");
140  size_t bytesRead = fread(&streamBuffer[0], sizeof(char), streamBuffer.size(), sys_profile);
141  pclose(sys_profile);
142 
143  // sometimes occurs when many I2C requests happen at the same time
144  if (bytesRead == 0)
145  {
146  oss << "CPU Type not found";
147  return oss.str();
148  }
149 
150  // read in the raw xml string and convert to an xml data structure
151  CFDataRef xmlData = CFDataCreate(kCFAllocatorDefault, (const UInt8*)&streamBuffer[0], bytesRead);
152  if (xmlData)
153  {
154  CFArrayRef propertyArray = CFArrayRef(CFPropertyListCreateWithData(kCFAllocatorDefault, xmlData, kCFPropertyListImmutable, NULL, NULL));
155  if (propertyArray)
156  {
157  CFDictionaryRef hwInfoDict = find_dict_for_data_type(propertyArray, CFSTR("SPDisplaysDataType"));
158  if (hwInfoDict)
159  {
160  CFArrayRef itemsArray = get_items_array_from_dict(hwInfoDict);
161  if (itemsArray)
162  {
163  // each item in array is a dictionary
164  for (CFIndex i=0; i < CFArrayGetCount(itemsArray); i++)
165  {
166  // find the string for key "sppci_model" which is the human readable name of the graphics card
167  CFDictionaryRef dict = CFDictionaryRef(CFArrayGetValueAtIndex(itemsArray, i));
168  CFStringRef key = CFSTR("sppci_model");
169  CFStringRef outputString = CFStringRef(CFDictionaryGetValue(dict, key));
170  if (outputString)
171  {
172  std::vector<char> tmp(CFStringGetLength(outputString)+1);
173  if (CFStringGetCString(outputString, &tmp[0], tmp.size(), kCFStringEncodingUTF8))
174  {
175  if (i != 0)
176  {
177  oss << ", ";
178  }
179  oss << &tmp[0];
180  }
181  CFRelease(outputString);
182  }
183  }
184  CFRelease(itemsArray);
185  }
186  CFRelease(hwInfoDict);
187  }
188  }
189  CFRelease(xmlData);
190  }
191 
192  return oss.str();
193 }
194 
196 {
197  mMemoryUnits = units;
198 }
199 
201 {
202 
203 }
204 
205 AJAStatus
207 {
209 
210  if (sections & AJA_SystemInfoSection_System)
211  {
212  ret = aja_sysctl("hw.model", mValueMap[int(AJA_SystemInfoTag_System_Model)]);
213  ret = aja_sysctl("kern.hostname", mValueMap[int(AJA_SystemInfoTag_System_Name)]);
214  ret = aja_sysctl("kern.boottime", mValueMap[int(AJA_SystemInfoTag_System_BootTime)]);
215  }
216 
217  if (sections & AJA_SystemInfoSection_OS)
218  {
219  ret = aja_sysctl("hw.targettype", mValueMap[int(AJA_SystemInfoTag_OS_ProductName)]);
220  ret = aja_sysctl("aja.osversion", mValueMap[int(AJA_SystemInfoTag_OS_Version)]);
221  ret = aja_sysctl("kern.osversion", mValueMap[int(AJA_SystemInfoTag_OS_VersionBuild)]);
222  ret = aja_sysctl("kern.version", mValueMap[int(AJA_SystemInfoTag_OS_KernelVersion)]);
223  }
224 
225  if (sections & AJA_SystemInfoSection_CPU)
226  {
227  ret = aja_sysctl("machdep.cpu.brand_string", mValueMap[int(AJA_SystemInfoTag_CPU_Type)]);
228  ret = aja_sysctl("hw.logicalcpu", mValueMap[int(AJA_SystemInfoTag_CPU_NumCores)]);
229  }
230 
231  if (sections & AJA_SystemInfoSection_Mem)
232  {
233  // memory is a little special
234  mach_msg_type_number_t count = HOST_VM_INFO64_COUNT;
235  vm_statistics64_data_t vmstat;
236  if(KERN_SUCCESS == host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info64_t)&vmstat, &count))
237  {
238  int64_t memtotalbytes;
239  size_t size = sizeof(memtotalbytes);
240  if (sysctlbyname("hw.memsize", (void *)&memtotalbytes, &size, NULL, 0) == 0)
241  {
242  double totalPages = vmstat.wire_count + vmstat.active_count + vmstat.inactive_count + vmstat.free_count;
243  double freePercent = (vmstat.free_count) / totalPages;
244  double usedPercent = (vmstat.inactive_count + vmstat.wire_count + vmstat.active_count) / totalPages;
245 
246  std::string unitsLabel;
247  double divisor = 1.0;
248  switch(mMemoryUnits)
249  {
250  default:
252  unitsLabel = "B";
253  break;
255  unitsLabel = "KB";
256  divisor = 1024.0;
257  break;
259  unitsLabel = "MB";
260  divisor = 1048576.0;
261  break;
263  unitsLabel = "GB";
264  divisor = 1073741824.0;
265  break;
266  }
267 
268  std::ostringstream t,u,f;
269  t << int64_t(memtotalbytes / divisor) << " " << unitsLabel;
270  u << int64_t(memtotalbytes * usedPercent / divisor) << " " << unitsLabel;
271  f << int64_t(memtotalbytes * freePercent / divisor) << " " << unitsLabel;
272 
273  mValueMap[int(AJA_SystemInfoTag_Mem_Total)] = t.str();
274  mValueMap[int(AJA_SystemInfoTag_Mem_Used)] = u.str();
275  mValueMap[int(AJA_SystemInfoTag_Mem_Free)] = f.str();
276 
277  ret = AJA_STATUS_SUCCESS;
278  }
279  }
280  } // end if (sections & AJA_SystemInfoSection_Mem)
281 
282  if (sections & AJA_SystemInfoSection_GPU)
283  {
285  ret = AJA_STATUS_SUCCESS;
286  }
287 
288  if (sections & AJA_SystemInfoSection_Path)
289  {
290  const char* homePath = getenv("HOME");
291  if (homePath != NULL)
292  {
295  mValueMap[int(AJA_SystemInfoTag_Path_PersistenceStoreUser)].append("/Library/Preferences/");
296  }
297 
298  mValueMap[int(AJA_SystemInfoTag_Path_PersistenceStoreSystem)] = "/Users/Shared/AJA/";
299 
300  mValueMap[int(AJA_SystemInfoTag_Path_Applications)] = "/Applications/";
301  mValueMap[int(AJA_SystemInfoTag_Path_Utilities)] = "/Applications/AJA Utilities/";
302  mValueMap[int(AJA_SystemInfoTag_Path_Firmware)] = "/Library/Application Support/AJA/Firmware/";
303 
304  ret = AJA_STATUS_SUCCESS;
305  }
306 
307  return ret;
308 }
AJA_SystemInfoSection_Path
@ AJA_SystemInfoSection_Path
Definition: info.h:61
info.h
Declares the AJASystemInfo class.
AJA_SystemInfoMemoryUnit_Megabytes
@ AJA_SystemInfoMemoryUnit_Megabytes
Definition: info.h:23
AJA_SystemInfoSection_CPU
@ AJA_SystemInfoSection_CPU
Definition: info.h:57
NULL
#define NULL
Definition: ntv2caption608types.h:19
AJA_STATUS_SUCCESS
@ AJA_STATUS_SUCCESS
Definition: types.h:381
AJA_SystemInfoTag_Path_Firmware
@ AJA_SystemInfoTag_Path_Firmware
Definition: info.h:50
AJASystemInfoImpl::mMemoryUnits
int mMemoryUnits
Definition: infoimpl.h:26
AJA_SystemInfoTag_OS_KernelVersion
@ AJA_SystemInfoTag_OS_KernelVersion
Definition: info.h:38
AJA_SystemInfoTag_Path_Applications
@ AJA_SystemInfoTag_Path_Applications
Definition: info.h:48
AJASystemInfoImpl::~AJASystemInfoImpl
virtual ~AJASystemInfoImpl()
Definition: infoimpl.cpp:251
AJA_SystemInfoMemoryUnit_Kilobytes
@ AJA_SystemInfoMemoryUnit_Kilobytes
Definition: info.h:22
AJA_SystemInfoTag_CPU_Type
@ AJA_SystemInfoTag_CPU_Type
Definition: info.h:39
aja_sysctl
static AJAStatus aja_sysctl(const char *name, std::string &result)
Definition: infoimpl.mm:19
AJAStatus
AJAStatus
Definition: types.h:378
AJA_SystemInfoTag_CPU_NumCores
@ AJA_SystemInfoTag_CPU_NumCores
Definition: info.h:40
AJA_STATUS_FAIL
@ AJA_STATUS_FAIL
Definition: types.h:382
AJA_SystemInfoTag_System_Name
@ AJA_SystemInfoTag_System_Name
Definition: info.h:33
AJASystemInfoImpl::mValueMap
std::map< int, std::string > mValueMap
Definition: infoimpl.h:24
AJA_SystemInfoTag_System_BootTime
@ AJA_SystemInfoTag_System_BootTime
Definition: info.h:34
AJA_SystemInfoTag_OS_Version
@ AJA_SystemInfoTag_OS_Version
Definition: info.h:36
AJA_SystemInfoTag_Mem_Used
@ AJA_SystemInfoTag_Mem_Used
Definition: info.h:42
get_items_array_from_dict
static CFArrayRef get_items_array_from_dict(const CFDictionaryRef inDictionary)
Definition: infoimpl.mm:122
AJA_SystemInfoSection_GPU
@ AJA_SystemInfoSection_GPU
Definition: info.h:58
AJA_SystemInfoTag_Path_PersistenceStoreUser
@ AJA_SystemInfoTag_Path_PersistenceStoreUser
Definition: info.h:46
AJASystemInfoSections
AJASystemInfoSections
Definition: info.h:55
AJASystemInfoImpl::AJASystemInfoImpl
AJASystemInfoImpl(int units)
Definition: infoimpl.cpp:246
AJA_SystemInfoTag_Path_PersistenceStoreSystem
@ AJA_SystemInfoTag_Path_PersistenceStoreSystem
Definition: info.h:47
system.h
System specific functions.
AJA_SystemInfoMemoryUnit_Gigabytes
@ AJA_SystemInfoMemoryUnit_Gigabytes
Definition: info.h:24
AJA_SystemInfoTag_OS_ProductName
@ AJA_SystemInfoTag_OS_ProductName
Definition: info.h:35
AJA_SystemInfoSection_OS
@ AJA_SystemInfoSection_OS
Definition: info.h:60
AJA_SystemInfoTag_Path_Utilities
@ AJA_SystemInfoTag_Path_Utilities
Definition: info.h:49
aja_getgputype
static std::string aja_getgputype(void)
Definition: infoimpl.mm:133
AJA_SystemInfoTag_Path_UserHome
@ AJA_SystemInfoTag_Path_UserHome
Definition: info.h:45
AJASystemInfoImpl::Rescan
virtual AJAStatus Rescan(AJASystemInfoSections sections)
Definition: infoimpl.cpp:257
AJA_SystemInfoSection_Mem
@ AJA_SystemInfoSection_Mem
Definition: info.h:59
AJA_SystemInfoTag_Mem_Free
@ AJA_SystemInfoTag_Mem_Free
Definition: info.h:43
AJA_SystemInfoTag_GPU_Type
@ AJA_SystemInfoTag_GPU_Type
Definition: info.h:44
infoimpl.h
Declares the AJASystemInfoImpl class.
find_dict_for_data_type
static CFDictionaryRef find_dict_for_data_type(const CFArrayRef inArray, CFStringRef inDataType)
Definition: infoimpl.mm:105
AJA_SystemInfoTag_OS_VersionBuild
@ AJA_SystemInfoTag_OS_VersionBuild
Definition: info.h:37
AJA_SystemInfoMemoryUnit_Bytes
@ AJA_SystemInfoMemoryUnit_Bytes
Definition: info.h:21
AJA_SystemInfoSection_System
@ AJA_SystemInfoSection_System
Definition: info.h:62
AJA_SystemInfoTag_Mem_Total
@ AJA_SystemInfoTag_Mem_Total
Definition: info.h:41
AJA_SystemInfoTag_System_Model
@ AJA_SystemInfoTag_System_Model
Definition: info.h:31