*** sqUnixSerial.c.orig 2005-03-20 05:38:19.000000000 +0900 --- sqUnixSerial.c 2005-10-21 12:03:35.000000000 +0900 *************** *** 8,29 **** * Ian Piumarta */ ! #include "sq.h" ! #include "SerialPlugin.h" ! #include #include #include #include #include #include /*** Module variables ***/ /* portNum 0=/dev/ttyS0, etc. */ /* include 1 byte for NUL at end */ #define PORT_NAME_SIZE 11 static const char serialPortBaseName[] = "/dev/ttyS0"; /* stopBits 0=1.5, 1=1, 2=2 */ /* I don't know how to get 1.5 stop bits. Oh well. So you get 2 instead */ --- 8,57 ---- * Ian Piumarta */ ! #include #include #include #include #include #include + #include #include + #if defined(__APPLE__) && defined(__POWERPC__) + #include + #include + #include + #include + #include + #include + + #ifdef __MWERKS__ + #define __CF_USE_FRAMEWORK_INCLUDES__ + #endif + + #include + + #include + #include + #if defined(MAC_OS_X_VERSION_10_3) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_3) + #include + #endif + #include + #endif /* defined(__APPLE__) && defined(__POWERPC__) */ + + #include "sq.h" + #include "SerialPlugin.h" + /*** Module variables ***/ + #if defined(__APPLE__) && defined(__POWERPC__) + #define PORT_NAME_SIZE 128 + #else /* portNum 0=/dev/ttyS0, etc. */ /* include 1 byte for NUL at end */ #define PORT_NAME_SIZE 11 static const char serialPortBaseName[] = "/dev/ttyS0"; + #endif /* stopBits 0=1.5, 1=1, 2=2 */ /* I don't know how to get 1.5 stop bits. Oh well. So you get 2 instead */ *************** *** 56,62 **** --- 84,92 ---- /* must be <= 10, because of 1-digit filename generation */ #define MAX_SERIAL_PORTS 10 static int serialFileDescriptors[MAX_SERIAL_PORTS]; /* index=squeak port# */ + #if !(defined(__APPLE__) && defined(__POWERPC__)) static struct termios savedSerialTermios[MAX_SERIAL_PORTS]; /* index=squeak port# */ + #endif /* dataRate rate in bps */ typedef struct drDecode { int dataRate; speed_t code; } drDecode; *************** *** 103,110 **** --- 133,142 ---- { -1, B0 } /* end marker */ }; + #if !(defined(__APPLE__) && defined(__POWERPC__)) /* This is the default setting for a termios structure on open */ static struct termios defaultTermios; + #endif /*** Private Functions ***/ *************** *** 121,126 **** --- 153,236 ---- return B0; } + #if defined(__APPLE__) && defined(__POWERPC__) + // Returns an iterator across all known modems. Caller is responsible for + // releasing the iterator when iteration is complete. + static kern_return_t FindSerialPorts(io_iterator_t *matchingServices) + { + kern_return_t kernResult; + CFMutableDictionaryRef classesToMatch; + + // Serial devices are instances of class IOSerialBSDClient + classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue); + if (classesToMatch == NULL) + { + printf("IOServiceMatching returned a NULL dictionary.\n"); + } + else + { + CFDictionarySetValue(classesToMatch, + CFSTR(kIOSerialBSDTypeKey), + CFSTR(kIOSerialBSDAllTypes)); + } + kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault, classesToMatch, matchingServices); + if (KERN_SUCCESS != kernResult) + { + printf("IOServiceGetMatchingServices returned %d\n", kernResult); + goto exit; + } + + exit: + return kernResult; + } + + // Given an iterator across a set of serials, return 1 and the BSD path to the portNum-th is set to bsdPath. + // If the portNum-th serial are NOT found, return 0. + static int GetSerialPath(int portNum, char *bsdPath, int maxPathLen) + { + io_iterator_t theSerialIterator; + io_object_t theObject; + kern_return_t kernResult = KERN_FAILURE; + int count = 0; + int flag = 0; + + if (FindSerialPorts(&theSerialIterator) != KERN_SUCCESS) + { + printf("createSerialIterator failed\n"); + return 0; + } + + while ((theObject = IOIteratorNext(theSerialIterator)) && (count < portNum)) + { + count++; + } + + if (theObject && (count == portNum)) + { + CFTypeRef bsdPathAsCFString; + + bsdPathAsCFString = IORegistryEntryCreateCFProperty(theObject, + CFSTR(kIOCalloutDeviceKey), + kCFAllocatorDefault, + 0); + if (bsdPathAsCFString) + { + Boolean result; + + result = CFStringGetCString(bsdPathAsCFString, + bsdPath, + maxPathLen, + kCFStringEncodingUTF8); + CFRelease(bsdPathAsCFString); + flag = 1; + } + // Release the io_service_t now that we are done with it. + (void) IOObjectRelease(theObject); + } + return flag; + } + #endif /* defined(__APPLE__) && defined(__POWERPC__) */ + /*** Public Functions ***/ /* return value ignored */ *************** *** 139,146 **** --- 249,260 ---- return 0; } serialFileDescriptors[ portNum ] = -1; + #if defined(__APPLE__) && defined(__POWERPC__) + if (close(fd)) + #else if (tcsetattr(fd, TCSAFLUSH, savedSerialTermios + portNum) || close(fd)) + #endif { success(false); return 0; *************** *** 186,193 **** --- 300,315 ---- } /* generate a filename (with last digit set to port number) */ + #if defined(__APPLE__) && defined(__POWERPC__) + if (GetSerialPath(portNum, serialPortName, PORT_NAME_SIZE) == 0) + { + success(false); + return 0; + } + #else strcpy(serialPortName, serialPortBaseName); serialPortName[ PORT_NAME_SIZE - 2 ] = portNum + '0'; + #endif /* open the device */ if ((fd = open(serialPortName, O_RDWR|O_NONBLOCK|O_NOCTTY)) < 0) *************** *** 199,212 **** --- 321,343 ---- serialFileDescriptors[ portNum ] = fd; /* save the old state */ + #if defined(__APPLE__) && defined(__POWERPC__) + if (tcgetattr(fd, &flags)) + #else if (tcgetattr(fd, savedSerialTermios + portNum)) + #endif { success(false); return 0; } + #if defined(__APPLE__) && defined(__POWERPC__) + cfmakeraw(&flags); + flags.c_cflag |= CLOCAL; + #else /* set up the new modes */ flags = defaultTermios; + #endif /* input & output data rate */ cfsetispeed(&flags, speed); *************** *** 265,271 **** int serialPortReadInto(int portNum, int count, int startPtr) { int fd; ! ssize_t bytesRead; void* buffer = (void*)startPtr; /* ints as pointers?? */ if (portNum < 0 --- 396,402 ---- int serialPortReadInto(int portNum, int count, int startPtr) { int fd; ! ssize_t bytesRead = 0; void* buffer = (void*)startPtr; /* ints as pointers?? */ if (portNum < 0 *************** *** 316,321 **** --- 447,455 ---- success(false); return 0; } + #if defined(__APPLE__) && defined(__POWERPC__) + tcdrain(fd); + #endif success(true); return bytesWritten; *************** *** 330,335 **** --- 464,470 ---- for (i = 0; i < MAX_SERIAL_PORTS; i++) serialFileDescriptors[ i ] = -1; + #if !(defined(__APPLE__) && defined(__POWERPC__)) /* initialize our default termios structure (already 0'd) */ defaultTermios.c_iflag = IGNBRK | IGNPAR; /* ignore break, parity/framing errs */ /* tcflag_t c_oflag output modes */ *************** *** 341,346 **** --- 476,482 ---- /* cc_t c_cc[NCCS] control chars */ defaultTermios.c_cc[VTIME] = 0; defaultTermios.c_cc[VMIN] = 0; + #endif /* !(defined(__APPLE__) && defined(__POWERPC__)) */ success(true); return 1;