1 /* 2 * Darwin serial port definitions, uses IOKit to build sysdev 3 * Loosely based on FreeBSD/deveia.c 4 * Copyright © 1998, 1999 Lucent Technologies Inc. All rights reserved. 5 * Revisions Copyright © 1999, 2000 Vita Nuova Limited. All rights reserved. 6 * Revisions Copyright © 2003 Corpus Callosum Corporation. All rights reserved. 7 */ 8 9 #include <termios.h> 10 #include <sys/param.h> 11 #include <stdio.h> 12 #include <unistd.h> 13 #include <stdlib.h> 14 15 #include <mach/mach.h> 16 17 #include <CoreFoundation/CFNumber.h> 18 19 #include <IOKit/IOKitLib.h> 20 #include <IOKit/IOCFPlugIn.h> 21 #include <IOKit/usb/IOUSBLib.h> 22 #include <IOKit/serial/IOSerialKeys.h> 23 #include <IOKit/IOBSD.h> 24 25 #include <sys/ioctl.h> 26 #include <sys/ttycom.h> 27 28 #undef nil 29 30 #define B14400 14400 31 #define B28800 28800 32 #define B57600 57600 33 #define B76800 76800 34 #define B115200 115200 35 #define B230400 230400 36 37 extern int vflag; 38 39 #define MAXDEV 16 40 static char *sysdev[MAXDEV]; 41 42 static void _buildsysdev(void); 43 #define buildsysdev() _buildsysdev() /* for devfs-posix.c */ 44 45 #include "deveia-posix.c" 46 #include "deveia-bsd.c" 47 48 static struct tcdef_t bps[] = { 49 {0, B0}, 50 {50, B50}, 51 {75, B75}, 52 {110, B110}, 53 {134, B134}, 54 {150, B150}, 55 {200, B200}, 56 {300, B300}, 57 {600, B600}, 58 {1200, B1200}, 59 {1800, B1800}, 60 {2400, B2400}, 61 {4800, B4800}, 62 {9600, B9600}, 63 {19200, B19200}, 64 {38400, B38400}, 65 {57600, B57600}, 66 {76800, B76800}, 67 {115200, B115200}, 68 {230400, B230400}, 69 {0, -1} 70 }; 71 72 static void 73 _buildsysdev(void) 74 { 75 mach_port_t port; 76 CFMutableDictionaryRef classesToMatch; 77 io_iterator_t serialPortIterator; 78 io_object_t serialDevice; 79 CFMutableArrayRef paths; 80 CFTypeRef path; 81 char eiapath[MAXPATHLEN]; 82 CFIndex i, o, npath; 83 84 if(IOMasterPort(MACH_PORT_NULL, &port) != KERN_SUCCESS) 85 return; 86 classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue); 87 if(classesToMatch == NULL){ 88 printf("IOServiceMatching returned a NULL dictionary.\n"); 89 goto Failed; 90 } 91 CFDictionarySetValue(classesToMatch, 92 CFSTR(kIOSerialBSDTypeKey), 93 CFSTR(kIOSerialBSDAllTypes)); 94 95 if(IOServiceGetMatchingServices(port, classesToMatch, &serialPortIterator) != KERN_SUCCESS) 96 goto Failed; 97 98 paths = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); 99 while((serialDevice = IOIteratorNext(serialPortIterator)) != 0){ 100 path = IORegistryEntryCreateCFProperty(serialDevice, CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, 0); 101 if(path != NULL) 102 CFArrayAppendValue(paths, path); 103 IOObjectRelease(serialDevice); 104 } 105 106 npath = CFArrayGetCount(paths); 107 o = 0; 108 for(i = 0; i < npath && i < nelem(sysdev); i++){ 109 if(CFStringGetCString(CFArrayGetValueAtIndex(paths, i), eiapath, sizeof(eiapath), kCFStringEncodingUTF8)){ 110 sysdev[o] = strdup(eiapath); 111 if(vflag) 112 print("BSD path: '%s'\n", sysdev[o]); 113 o++; 114 } 115 } 116 117 CFRelease(paths); 118 IOObjectRelease(serialPortIterator); 119 120 Failed: 121 mach_port_deallocate(mach_task_self(), port); 122 } 123 124