OpenCPN Partial API docs
Loading...
Searching...
No Matches
macutils.c
Go to the documentation of this file.
1/***************************************************************************
2 * Copyright (C) 2007 - 2010 by David S. Register, Richard M Smith *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, see <https://www.gnu.org/licenses/>. *
16 **************************************************************************/
17
24#ifdef __APPLE__
25
26#include <errno.h>
27#include <fcntl.h>
28#include <paths.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <sysexits.h>
33#include <sys/ioctl.h>
34#include <sys/param.h>
35#include <sys/select.h>
36#include <sys/sysctl.h>
37#include <sys/time.h>
38#include <termios.h>
39#include <time.h>
40#include <unistd.h>
41
42#include <AvailabilityMacros.h>
43#include <CoreFoundation/CoreFoundation.h>
44#include <IOKit/IOKitLib.h>
45#include <IOKit/serial/IOSerialKeys.h>
46#include <IOKit/IOBSD.h>
47
48#if defined(MAC_OS_X_VERSION_10_3) && \
49 (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_3)
50#include <IOKit/serial/ioss.h>
51#endif
52
53// We need CoreGraphics to read the monitor physical size.
54// In 10.7 CoreGraphics is part of ApplicationServices.
55#include <ApplicationServices/ApplicationServices.h>
56// When we stop building against 10.7 we will probably want to link agains
57// CoreGraphics directly:
58// #include <CoreGraphics/CoreGraphics.h>
59
60#include "config.h"
61
62// Returns an iterator across all known serial ports. Caller is responsible for
63// releasing the iterator when iteration is complete.
64static kern_return_t FindSerialPorts(io_iterator_t* matchingServices) {
65 kern_return_t kernResult;
66 CFMutableDictionaryRef classesToMatch;
67
83 // Serial devices are instances of class IOSerialBSDClient
84 classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue);
85 if (classesToMatch == NULL) {
86 printf("IOServiceMatching returned a NULL dictionary.\n");
87 } else {
110 CFDictionarySetValue(classesToMatch, CFSTR(kIOSerialBSDTypeKey),
111 CFSTR(kIOSerialBSDAllTypes));
112
113 // Each serial device object has a property with key
114 // kIOSerialBSDTypeKey and a value that is one of kIOSerialBSDAllTypes,
115 // kIOSerialBSDModemType, or kIOSerialBSDRS232Type. You can experiment with
116 // the matching by changing the last parameter in the above call to
117 // CFDictionarySetValue.
118
119 // As shipped, this sample is only interested in serial ports,
120 // so add this property to the CFDictionary we're matching on.
121 // This will find devices that advertise themselves as serial ports,
122 // such as built-in and USB serial ports. However, this match won't find
123 // serial serial ports.
124 }
125
143 kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault,
144 classesToMatch, matchingServices);
145 if (KERN_SUCCESS != kernResult) {
146 printf("IOServiceGetMatchingServices returned %d\n", kernResult);
147 goto exit;
148 }
149
150exit:
151 return kernResult;
152}
153
154// Given an iterator across a set of serial ports, return the BSD path to the
155// first one. If no serial ports are found the path name is set to an empty
156// string.
157static int GetSerialPortPath(io_iterator_t serialPortIterator, char** pNames,
158 int iMaxNames, CFIndex maxPathSize) {
159 io_object_t modemService;
160 // kern_return_t kernResult = KERN_FAILURE;
161 Boolean modemFound = false;
162 char bsdPath[maxPathSize];
163 int iCurrentNameIndex = 0;
164 // Initialize the returned path
165 *bsdPath = '\0';
166
167 // Iterate across all serial ports found.
168
169 while ((modemService = IOIteratorNext(serialPortIterator)) && !modemFound) {
170 CFTypeRef bsdPathAsCFString;
171
172 // Get the callout device's path (/dev/cu.xxxxx). The callout device should
173 // almost always be used: the dialin device (/dev/tty.xxxxx) would be used
174 // when monitoring a serial port for incoming calls, e.g. a fax listener.
175
176 bsdPathAsCFString = IORegistryEntryCreateCFProperty(
177 modemService, CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, 0);
178 if (bsdPathAsCFString) {
179 Boolean result;
180
181 // Convert the path from a CFString to a C (NUL-terminated) string for use
182 // with the POSIX open() call.
183
184 result = CFStringGetCString(bsdPathAsCFString, bsdPath, maxPathSize,
185 kCFStringEncodingUTF8);
186 CFRelease(bsdPathAsCFString);
187
188 if (result) {
189 pNames[iCurrentNameIndex] = calloc(1, strlen(bsdPath) + 1);
190 strncpy(pNames[iCurrentNameIndex], bsdPath, strlen(bsdPath) + 1);
191 iCurrentNameIndex++;
192 }
193 }
194 // Release the io_service_t now that we are done with it.
195 (void)IOObjectRelease(modemService);
196 }
197 return iCurrentNameIndex;
198}
199
200int FindSerialPortNames(char** pNames, int iMaxNames) {
201 int iActiveNameCount = 0;
202 kern_return_t kernResult; // on PowerPC this is an int (4 bytes)
203
204 io_iterator_t serialPortIterator;
205
206 kernResult = FindSerialPorts(&serialPortIterator);
207
208 iActiveNameCount =
209 GetSerialPortPath(serialPortIterator, pNames, iMaxNames, MAXPATHLEN);
210
211 IOObjectRelease(serialPortIterator); // Release the iterator.
212 return iActiveNameCount;
213}
214
215bool ValidateSerialPortName(char* pPortName, int iMaxNamestoSearch) {
216 char* paPortNames[iMaxNamestoSearch];
217 int iPortNameCount;
218 int iPortIndex;
219 bool bPortFound = false;
220 char* pPortSubName = index(pPortName, ':');
221 // name is always valid if opetion is set to 'none'
222 if (0 == strcasecmp(pPortName, "NONE")) return true;
223 // if this name done not have a leading descriptor with a 'serial:', 'GPS:',
224 // etc, use the whole name
225 if (NULL == pPortSubName)
226 pPortSubName = pPortName;
227 else
228 pPortSubName++;
229
230 memset(paPortNames, 0x00, sizeof(paPortNames));
231 iPortNameCount = FindSerialPortNames(&paPortNames[0], iMaxNamestoSearch);
232 for (iPortIndex = 0; iPortIndex < iPortNameCount; iPortIndex++) {
233 // stripoff leading 'serial:', etc based on iColonIndex
234 int iStrCompresult = strcmp(paPortNames[iPortIndex], pPortSubName);
235 if (false == bPortFound) bPortFound = (bool)(0 == iStrCompresult);
236 free(paPortNames[iPortIndex]);
237 }
238 return bPortFound;
239}
240
244int GetMacMonitorSize() {
245 CGSize displayPhysicalSize = CGDisplayScreenSize(CGMainDisplayID()); // mm
246 return displayPhysicalSize.width;
247}
248
254int ProcessIsTranslated() {
255 int ret = 0;
256 size_t size = sizeof(ret);
257 if (sysctlbyname("sysctl.proc_translated", &ret, &size, NULL, 0) == -1) {
258 if (errno == ENOENT) return 0;
259 return -1;
260 }
261 return ret;
262}
263
264int IsAppleSilicon() {
265 int ret = 0;
266 size_t size = sizeof(ret);
267
268 if (sysctlbyname("hw.optional.arm64", &ret, &size, NULL, 0) == -1) {
269 return -1;
270 }
271 return ret;
272}
273
274#endif //__WXOSX__