137da2899SCharles.Forsyth /*
237da2899SCharles.Forsyth * Darwin serial port definitions, uses IOKit to build sysdev
337da2899SCharles.Forsyth * Loosely based on FreeBSD/deveia.c
437da2899SCharles.Forsyth * Copyright © 1998, 1999 Lucent Technologies Inc. All rights reserved.
537da2899SCharles.Forsyth * Revisions Copyright © 1999, 2000 Vita Nuova Limited. All rights reserved.
637da2899SCharles.Forsyth * Revisions Copyright © 2003 Corpus Callosum Corporation. All rights reserved.
737da2899SCharles.Forsyth */
837da2899SCharles.Forsyth
937da2899SCharles.Forsyth #include <termios.h>
1037da2899SCharles.Forsyth #include <sys/param.h>
1137da2899SCharles.Forsyth #include <stdio.h>
1237da2899SCharles.Forsyth #include <unistd.h>
1337da2899SCharles.Forsyth #include <stdlib.h>
1437da2899SCharles.Forsyth
1537da2899SCharles.Forsyth #include <mach/mach.h>
1637da2899SCharles.Forsyth
1737da2899SCharles.Forsyth #include <CoreFoundation/CFNumber.h>
1837da2899SCharles.Forsyth
1937da2899SCharles.Forsyth #include <IOKit/IOKitLib.h>
2037da2899SCharles.Forsyth #include <IOKit/IOCFPlugIn.h>
2137da2899SCharles.Forsyth #include <IOKit/usb/IOUSBLib.h>
2237da2899SCharles.Forsyth #include <IOKit/serial/IOSerialKeys.h>
2337da2899SCharles.Forsyth #include <IOKit/IOBSD.h>
2437da2899SCharles.Forsyth
257b2a26f5SCharles Forsyth #include <sys/ioctl.h>
267b2a26f5SCharles Forsyth #include <sys/ttycom.h>
277b2a26f5SCharles Forsyth
287b2a26f5SCharles Forsyth #undef nil
297b2a26f5SCharles Forsyth
3037da2899SCharles.Forsyth #define B14400 14400
3137da2899SCharles.Forsyth #define B28800 28800
3237da2899SCharles.Forsyth #define B57600 57600
3337da2899SCharles.Forsyth #define B76800 76800
3437da2899SCharles.Forsyth #define B115200 115200
3537da2899SCharles.Forsyth #define B230400 230400
3637da2899SCharles.Forsyth
3737da2899SCharles.Forsyth extern int vflag;
3837da2899SCharles.Forsyth
397b2a26f5SCharles Forsyth #define MAXDEV 16
4037da2899SCharles.Forsyth static char *sysdev[MAXDEV];
4137da2899SCharles.Forsyth
4237da2899SCharles.Forsyth static void _buildsysdev(void);
4337da2899SCharles.Forsyth #define buildsysdev() _buildsysdev() /* for devfs-posix.c */
4437da2899SCharles.Forsyth
4537da2899SCharles.Forsyth #include "deveia-posix.c"
4637da2899SCharles.Forsyth #include "deveia-bsd.c"
4737da2899SCharles.Forsyth
4837da2899SCharles.Forsyth static struct tcdef_t bps[] = {
4937da2899SCharles.Forsyth {0, B0},
5037da2899SCharles.Forsyth {50, B50},
5137da2899SCharles.Forsyth {75, B75},
5237da2899SCharles.Forsyth {110, B110},
5337da2899SCharles.Forsyth {134, B134},
5437da2899SCharles.Forsyth {150, B150},
5537da2899SCharles.Forsyth {200, B200},
5637da2899SCharles.Forsyth {300, B300},
5737da2899SCharles.Forsyth {600, B600},
5837da2899SCharles.Forsyth {1200, B1200},
5937da2899SCharles.Forsyth {1800, B1800},
6037da2899SCharles.Forsyth {2400, B2400},
6137da2899SCharles.Forsyth {4800, B4800},
6237da2899SCharles.Forsyth {9600, B9600},
6337da2899SCharles.Forsyth {19200, B19200},
6437da2899SCharles.Forsyth {38400, B38400},
6537da2899SCharles.Forsyth {57600, B57600},
6637da2899SCharles.Forsyth {76800, B76800},
6737da2899SCharles.Forsyth {115200, B115200},
6837da2899SCharles.Forsyth {230400, B230400},
6937da2899SCharles.Forsyth {0, -1}
7037da2899SCharles.Forsyth };
717b2a26f5SCharles Forsyth
727b2a26f5SCharles Forsyth static void
_buildsysdev(void)737b2a26f5SCharles Forsyth _buildsysdev(void)
747b2a26f5SCharles Forsyth {
757b2a26f5SCharles Forsyth mach_port_t port;
767b2a26f5SCharles Forsyth CFMutableDictionaryRef classesToMatch;
777b2a26f5SCharles Forsyth io_iterator_t serialPortIterator;
787b2a26f5SCharles Forsyth io_object_t serialDevice;
797b2a26f5SCharles Forsyth CFMutableArrayRef paths;
807b2a26f5SCharles Forsyth CFTypeRef path;
817b2a26f5SCharles Forsyth char eiapath[MAXPATHLEN];
827b2a26f5SCharles Forsyth CFIndex i, o, npath;
837b2a26f5SCharles Forsyth
847b2a26f5SCharles Forsyth if(IOMasterPort(MACH_PORT_NULL, &port) != KERN_SUCCESS)
857b2a26f5SCharles Forsyth return;
867b2a26f5SCharles Forsyth classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue);
877b2a26f5SCharles Forsyth if(classesToMatch == NULL){
887b2a26f5SCharles Forsyth printf("IOServiceMatching returned a NULL dictionary.\n");
897b2a26f5SCharles Forsyth goto Failed;
907b2a26f5SCharles Forsyth }
917b2a26f5SCharles Forsyth CFDictionarySetValue(classesToMatch,
927b2a26f5SCharles Forsyth CFSTR(kIOSerialBSDTypeKey),
937b2a26f5SCharles Forsyth CFSTR(kIOSerialBSDAllTypes));
947b2a26f5SCharles Forsyth
957b2a26f5SCharles Forsyth if(IOServiceGetMatchingServices(port, classesToMatch, &serialPortIterator) != KERN_SUCCESS)
967b2a26f5SCharles Forsyth goto Failed;
977b2a26f5SCharles Forsyth
987b2a26f5SCharles Forsyth paths = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
997b2a26f5SCharles Forsyth while((serialDevice = IOIteratorNext(serialPortIterator)) != 0){
1007b2a26f5SCharles Forsyth path = IORegistryEntryCreateCFProperty(serialDevice, CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, 0);
1017b2a26f5SCharles Forsyth if(path != NULL)
1027b2a26f5SCharles Forsyth CFArrayAppendValue(paths, path);
1037b2a26f5SCharles Forsyth IOObjectRelease(serialDevice);
1047b2a26f5SCharles Forsyth }
1057b2a26f5SCharles Forsyth
1067b2a26f5SCharles Forsyth npath = CFArrayGetCount(paths);
1077b2a26f5SCharles Forsyth o = 0;
1087b2a26f5SCharles Forsyth for(i = 0; i < npath && i < nelem(sysdev); i++){
1097b2a26f5SCharles Forsyth if(CFStringGetCString(CFArrayGetValueAtIndex(paths, i), eiapath, sizeof(eiapath), kCFStringEncodingUTF8)){
1107b2a26f5SCharles Forsyth sysdev[o] = strdup(eiapath);
111a3b48c04SCharles Forsyth if(vflag > 1)
112*aa479b94SCharles Forsyth print("deveia path: eia%d -> '%s'\n", o, sysdev[o]);
1137b2a26f5SCharles Forsyth o++;
1147b2a26f5SCharles Forsyth }
1157b2a26f5SCharles Forsyth }
1167b2a26f5SCharles Forsyth
1177b2a26f5SCharles Forsyth CFRelease(paths);
1187b2a26f5SCharles Forsyth IOObjectRelease(serialPortIterator);
1197b2a26f5SCharles Forsyth
1207b2a26f5SCharles Forsyth Failed:
1217b2a26f5SCharles Forsyth mach_port_deallocate(mach_task_self(), port);
1227b2a26f5SCharles Forsyth }
1237b2a26f5SCharles Forsyth
124