> I'm about at my wits end trying to get the serial code for a Carbonized
> CFM application to work in OSX, and would greatly appreciate any help that
[quoted text clipped - 13 lines]
> syntax errors in the exception handler UPP definitions, and type conflicts
> in the CFXxxx classes.
You would also need to change your includes (ie #include
<HIToolbox/Controls.h> instead of #include <Controls.h> (although for that
one you can just use #include <Carbon/Carbon.h>), change libraries you
link against etc.
What I would do is make a bundle that does your IOKit stuff. Your CFM
app can then load your bundle, extract whatever function pointers are
exported by it and call those.
Fred
> So I thought I'd try it a different way.
>
[quoted text clipped - 17 lines]
>
> Thanks in advance.
> I'm about at my wits end trying to get the serial code for a Carbonized
> CFM application to work in OSX, and would greatly appreciate any help that
[quoted text clipped - 6 lines]
> straight POSIX C code that will do both, but I can't get either to compile
> with the CFM app in CodeWarrior 8.3.
I've had a lot of experience with this, so let me describe what I do:
I've got a Carbon CFM app.
To get it to compile, I made a new target, a static library, and put the OS X
serial port in that. That way, it can have its own access paths, without
affecting the rest of my application.
Here are the access paths I use for that part of the code:
{OS X Volume}usr/include
{Compiler}MSL
{Compiler}Mac OS Support
{Compiler}Mac OS X Support
where only the last three have the recursive flag (the second column in
access paths) turn on.
The start of my source file looks like this:
#include <Carbon.h>
#include "CarbonSerialPortX.h"
#include "CRegistryOSX.h"
#include <fcntl.h>
#include <sys/filio.h>
#include <termios.h>
#include <time.h>
typedef unsigned int natural_t; // vm_types.h
typedef int integer_t; // vm_types.h
typedef long kern_return_t;
typedef unsigned int mach_port_t;
typedef mach_port_t io_object_t;
typedef io_object_t io_iterator_t;
typedef io_object_t io_registry_entry_t;
typedef UInt32 IOOptionBits;
typedef natural_t thread_policy_flavor_t;
typedef integer_t *thread_policy_t;
typedef natural_t mach_msg_type_number_t; // mach/message.h
typedef mach_port_t thread_act_t; // mach_types.h
When it became too difficult to #include what I needed, I just copied
the definitions to get the code to compile.
Under OS X, it does the following to enumerate the serial ports:
// ---------------------------------------------------------------------------
// € InitSerialPortArray
// ---------------------------------------------------------------------------
#define MACH_PORT_NULL 0
#define kIOSerialBSDServiceValue "IOSerialBSDClient"
#define kIOSerialBSDTypeKey "IOSerialBSDClientType"
#define kIOSerialBSDRS232Type "IORS232SerialStream"
#define kIOTTYDeviceKey "IOTTYDevice"
static CarbonSerialPortX ** sH;
static OSStatus InitSerialPortArray(void){
OSStatus err = noErr;
mach_port_t masterPort;
CFMutableDictionaryRef classesToMatch;
io_iterator_t serialPortIterator = NULL;
io_object_t serialService = NULL;
if(NULL == sH){
sH = (CarbonSerialPortX **) NewHandle(0);
}else{
SetHandleSize((Handle) sH, 0);
}
err = (*ioMasterPort)(MACH_PORT_NULL, &masterPort);
if(noErr == err && NULL == (classesToMatch = (*ioServiceMatching)(kIOSerialBSDServiceValue))){
err = paramErr;
}
if(noErr == err){
CFDictionarySetValue(classesToMatch,
CFSTR(kIOSerialBSDTypeKey),
CFSTR(kIOSerialBSDRS232Type));
}
if(noErr == err){ err = (*ioServiceGetMatchingServices)(masterPort, classesToMatch, &serialPortIterator); }
while (noErr == err && NULL != (serialService = (*ioIteratorNext)(serialPortIterator)))
{
CFTypeRef bsdPathAsCFString;
CarbonSerialPortX port = {0};
Boolean result;
bsdPathAsCFString = (*ioRegistryEntryCreateCFProperty)(serialService,
CFSTR(kIOTTYDeviceKey),
kCFAllocatorDefault,
0);
result = CFStringGetPascalString(bsdPathAsCFString,
port.userName,
sizeof port.userName,
kCFStringEncodingASCII);
CFRelease(bsdPathAsCFString);
(*ioObjectRelease)(serialService);
port.deviceName[0] = 0;
if('/' != port.userName[1]){
Concat(port.deviceName, "\p/dev/cu."); // use /dev/cu.* for non-blocking I/O on Keyspan serial port
//Concat(port.deviceName, "\p/dev/tty."); // /dev/tty.* blocks on I/O
}
Concat(port.deviceName, port.userName);
// append port to the handle of ports.
port.originalTTYAttrs = (struct termios*) NewPtrClear(sizeof(struct termios));
err = PtrAndHand(&port, (Handle) sH, sizeof port);
port.originalTTYAttrs = NULL;
}
if(NULL != sH){
HLock((Handle) sH);
}
// clean up
if(NULL != serialPortIterator){
OSStatus e = (*ioObjectRelease)(serialPortIterator);
if(noErr == err){ err = e; }
}
if(NULL != masterPort){
OSStatus e = (*ioObjectRelease)(masterPort);
if(noErr == err){ err = e; }
}
return err;
}
And the following code to initialize the function pointers:
(the reinterpret_cast_ macros are because this source file has moved back and
forth from C to C++ multiple times.)
// ---------------------------------------------------------------------------
// € InitFuncPointers
// ---------------------------------------------------------------------------
/// InitFuncPointers - initialize our dynamicly loaded function pointers to system calls.
OSStatus InitFuncPointers(void){
OSStatus err = noErr;
if(NULL == ioMasterPort){
CFBundleRef sysBundle;
if (NULL == ioKitBundle) {
CRegistryOSXInit();
if(NULL == ioKitBundle){
err = paramErr;
}
}
if (noErr == err) {
ioMasterPort = reinterpret_cast_(IOMasterPortProc)(CFBundleGetFunctionPointerForName(ioKitBundle, CFSTR("IOMasterPort")));
ioServiceMatching = reinterpret_cast_(IOServiceMatchingProc)(CFBundleGetFunctionPointerForName(ioKitBundle, CFSTR("IOServiceMatching")));
ioObjectRelease = reinterpret_cast_(IOObjectReleaseProc)(CFBundleGetFunctionPointerForName(ioKitBundle, CFSTR("IOObjectRelease")));
ioIteratorNext = reinterpret_cast_(IOIteratorNextProc)(CFBundleGetFunctionPointerForName(ioKitBundle, CFSTR("IOIteratorNext")));
ioRegistryEntryCreateCFProperty = reinterpret_cast_(IORegistryEntryCreateCFPropertyProc)(CFBundleGetFunctionPointerForName(ioKitBundle, CFSTR("IORegistryEntryCreateCFProperty")));
ioServiceGetMatchingServices = reinterpret_cast_(IOServiceGetMatchingServicesProc)(CFBundleGetFunctionPointerForName(ioKitBundle, CFSTR("IOServiceGetMatchingServices")));
}
if(noErr == err){
err = LoadFrameworkBundle(CFSTR("System.framework"), &sysBundle);
}
if(noErr == err){
// see: errno.h in the System framework for the reasoning behind the next line
errnop = reinterpret_cast_(ErrnoProc)(CFBundleGetFunctionPointerForName(sysBundle, CFSTR("__error")));
openp = reinterpret_cast_(OpenProc)(CFBundleGetFunctionPointerForName(sysBundle, CFSTR("open")));
closep = reinterpret_cast_(CloseProc)(CFBundleGetFunctionPointerForName(sysBundle, CFSTR("close")));
fcntlp = reinterpret_cast_(FcntlProc)(CFBundleGetFunctionPointerForName(sysBundle, CFSTR("fcntl")));
readp = reinterpret_cast_(ReadProc)(CFBundleGetFunctionPointerForName(sysBundle, CFSTR("read")));
writep = reinterpret_cast_(WriteProc)(CFBundleGetFunctionPointerForName(sysBundle, CFSTR("write")));
ioctlp = reinterpret_cast_(IoctlProc)(CFBundleGetFunctionPointerForName(sysBundle, CFSTR("ioctl")));
tcdrainp = reinterpret_cast_(TcdrainProc)(CFBundleGetFunctionPointerForName(sysBundle, CFSTR("tcdrain")));
tcgetattrp = reinterpret_cast_(TcgetattrProc)(CFBundleGetFunctionPointerForName(sysBundle, CFSTR("tcgetattr")));
tcsetattrp = reinterpret_cast_(TcsetattrProc)(CFBundleGetFunctionPointerForName(sysBundle, CFSTR("tcsetattr")));
cfsetspeedp = reinterpret_cast_(CfsetspeedProc)(CFBundleGetFunctionPointerForName(sysBundle, CFSTR("cfsetspeed")));
cfmakerawp = reinterpret_cast_(CfmakerawProc)(CFBundleGetFunctionPointerForName(sysBundle, CFSTR("cfmakeraw")));
mach_thread_selfp = reinterpret_cast_(MachThreadSelfProc)(CFBundleGetFunctionPointerForName(sysBundle, CFSTR("mach_thread_self")));
sysctlp = reinterpret_cast_(SysctlProc)(CFBundleGetFunctionPointerForName(sysBundle, CFSTR("sysctl")));
}
}
return err;
}
My problem is that under OS 9, I have analgous code to dynamicly attach
to InterfaceLib and pull the function pointers I need out of that, but
while CRMSearch() correctly enumerates the ports under Classic, it returns
0 ports when called from Carbon this way. Does anyone have a solution?

Signature
David Phillip Oster
The Berkeley Developers' Group (a free, public, gathering of programmers)
meets every other Wednesday Night, starting around 7:10 pm in the back room
of The Original Burger (formerly Mel's) 2240 Shattuck Ave - at Kittredge
Street, Berkeley, CA. Next meeting is Jan 28, 2004
Phil - 26 Jan 2004 16:30 GMT
David,
Thanks so much for this help! It is really useful to finally be pointed
in the right direction. I've started down this path and have met with
moderate success so far.
The biggest problem so far has been in getting the definitions for types
like your "IOMasterPortProc", which presumably are included from your
CRegistryOSX.h.
I haven't been able to include the necessary Frameworks headers to define
these properly. I did manage to get one working by scratching up my own
typedef, but my code won't be very portable and it would be a lot of work
to do this for the all of the pointers. A peek at how you define all
these Proc pointers could save me a great deal of time.
Thanks!
> > I'm about at my wits end trying to get the serial code for a Carbonized
> > CFM application to work in OSX, and would greatly appreciate any help that
[quoted text clipped - 96 lines]
> CFSTR(kIOTTYDeviceKey),
>
kCFAllocatorDefault,
> 0);
> result = CFStringGetPascalString(bsdPathAsCFString,
[quoted text clipped - 51 lines]
> if (noErr == err) {
> ioMasterPort = reinterpret_cast_(IOMasterPortProc)(CFBundleGetFunctionPointerForName(ioKitBundle,
CFSTR("IOMasterPort")));
> ioServiceMatching = reinterpret_cast_(IOServiceMatchingProc)(CFBundleGetFunctionPointerForName(ioKitBundle,
CFSTR("IOServiceMatching")));
> ioObjectRelease = reinterpret_cast_(IOObjectReleaseProc)(CFBundleGetFunctionPointerForName(ioKitBundle,
CFSTR("IOObjectRelease")));
> ioIteratorNext = reinterpret_cast_(IOIteratorNextProc)(CFBundleGetFunctionPointerForName(ioKitBundle,
CFSTR("IOIteratorNext")));
> ioRegistryEntryCreateCFProperty = reinterpret_cast_(IORegistryEntryCreateCFPropertyProc)(CFBundleGetFunctionPointerForName(ioKitBundle,
CFSTR("IORegistryEntryCreateCFProperty")));
> ioServiceGetMatchingServices = reinterpret_cast_(IOServiceGetMatchingServicesProc)(CFBundleGetFunctionPointerForName(ioKitBundle,
CFSTR("IOServiceGetMatchingServices")));
> }
> if(noErr == err){
[quoted text clipped - 3 lines]
> // see: errno.h in the System framework for the reasoning behind the next line
> errnop = reinterpret_cast_(ErrnoProc)(CFBundleGetFunctionPointerForName(sysBundle,
CFSTR("__error")));
> openp = reinterpret_cast_(OpenProc)(CFBundleGetFunctionPointerForName(sysBundle,
CFSTR("open")));
> closep = reinterpret_cast_(CloseProc)(CFBundleGetFunctionPointerForName(sysBundle,
CFSTR("close")));
> fcntlp = reinterpret_cast_(FcntlProc)(CFBundleGetFunctionPointerForName(sysBundle,
CFSTR("fcntl")));
> readp = reinterpret_cast_(ReadProc)(CFBundleGetFunctionPointerForName(sysBundle,
CFSTR("read")));
> writep = reinterpret_cast_(WriteProc)(CFBundleGetFunctionPointerForName(sysBundle,
CFSTR("write")));
> ioctlp = reinterpret_cast_(IoctlProc)(CFBundleGetFunctionPointerForName(sysBundle,
CFSTR("ioctl")));
> tcdrainp = reinterpret_cast_(TcdrainProc)(CFBundleGetFunctionPointerForName(sysBundle,
CFSTR("tcdrain")));
> tcgetattrp = reinterpret_cast_(TcgetattrProc)(CFBundleGetFunctionPointerForName(sysBundle,
CFSTR("tcgetattr")));
> tcsetattrp = reinterpret_cast_(TcsetattrProc)(CFBundleGetFunctionPointerForName(sysBundle,
CFSTR("tcsetattr")));
> cfsetspeedp = reinterpret_cast_(CfsetspeedProc)(CFBundleGetFunctionPointerForName(sysBundle,
CFSTR("cfsetspeed")));
> cfmakerawp = reinterpret_cast_(CfmakerawProc)(CFBundleGetFunctionPointerForName(sysBundle,
CFSTR("cfmakeraw")));
> mach_thread_selfp = reinterpret_cast_(MachThreadSelfProc)(CFBundleGetFunctionPointerForName(sysBundle,
CFSTR("mach_thread_self")));
> sysctlp = reinterpret_cast_(SysctlProc)(CFBundleGetFunctionPointerForName(sysBundle,
CFSTR("sysctl")));
> }
> }
[quoted text clipped - 5 lines]
> while CRMSearch() correctly enumerates the ports under Classic, it returns
> 0 ports when called from Carbon this way. Does anyone have a solution?
Phil - 27 Jan 2004 02:54 GMT
HOOORAY!!!
I actually have things compiling now!!! Thanks so much for your help in
getting me this far!
I can now open the port and set the attributes OK, but I get an error when
I try to read from it. (errno is 9, bad file descriptor.) Perhaps my
function prototype is wrong? This is one area where I'm really not sure
about things. I think this could be the problem because the file
descriptor was fine for the call to tcsetaddr().
Here is what I am doing:
--------
typedef pascal int (*TcsetattrProc)(int, int, const struct termios *);
typedef pascal size_t (*ReadProc)(int, void *, size_t);
static TcsetattrProc sTcsetattrProc;
static ReadProc sReadProc;
sTcsetattrProc =
(TcsetattrProc)(CFBundleGetFunctionPointerForName(sSysBundle,
CFSTR("tcsetattr")));
sReadProc = (ReadProc)(CFBundleGetFunctionPointerForName(sSysBundle,
CFSTR("read")));
// This works OK (returns 0) --
int err = sTcsetattrProc(mFileDescriptor, TCSANOW, &mCurrentTTYAttrs);
// but this gives an error --
int num = sReadProc(mFileDescriptor, buff, 10);
--------
Any ideas?? I'm getting close now!
Phil
> > I'm about at my wits end trying to get the serial code for a Carbonized
> > CFM application to work in OSX, and would greatly appreciate any help that
[quoted text clipped - 96 lines]
> CFSTR(kIOTTYDeviceKey),
>
kCFAllocatorDefault,
> 0);
> result = CFStringGetPascalString(bsdPathAsCFString,
[quoted text clipped - 51 lines]
> if (noErr == err) {
> ioMasterPort = reinterpret_cast_(IOMasterPortProc)(CFBundleGetFunctionPointerForName(ioKitBundle,
CFSTR("IOMasterPort")));
> ioServiceMatching = reinterpret_cast_(IOServiceMatchingProc)(CFBundleGetFunctionPointerForName(ioKitBundle,
CFSTR("IOServiceMatching")));
> ioObjectRelease = reinterpret_cast_(IOObjectReleaseProc)(CFBundleGetFunctionPointerForName(ioKitBundle,
CFSTR("IOObjectRelease")));
> ioIteratorNext = reinterpret_cast_(IOIteratorNextProc)(CFBundleGetFunctionPointerForName(ioKitBundle,
CFSTR("IOIteratorNext")));
> ioRegistryEntryCreateCFProperty = reinterpret_cast_(IORegistryEntryCreateCFPropertyProc)(CFBundleGetFunctionPointerForName(ioKitBundle,
CFSTR("IORegistryEntryCreateCFProperty")));
> ioServiceGetMatchingServices = reinterpret_cast_(IOServiceGetMatchingServicesProc)(CFBundleGetFunctionPointerForName(ioKitBundle,
CFSTR("IOServiceGetMatchingServices")));
> }
> if(noErr == err){
[quoted text clipped - 3 lines]
> // see: errno.h in the System framework for the reasoning behind the next line
> errnop = reinterpret_cast_(ErrnoProc)(CFBundleGetFunctionPointerForName(sysBundle,
CFSTR("__error")));
> openp = reinterpret_cast_(OpenProc)(CFBundleGetFunctionPointerForName(sysBundle,
CFSTR("open")));
> closep = reinterpret_cast_(CloseProc)(CFBundleGetFunctionPointerForName(sysBundle,
CFSTR("close")));
> fcntlp = reinterpret_cast_(FcntlProc)(CFBundleGetFunctionPointerForName(sysBundle,
CFSTR("fcntl")));
> readp = reinterpret_cast_(ReadProc)(CFBundleGetFunctionPointerForName(sysBundle,
CFSTR("read")));
> writep = reinterpret_cast_(WriteProc)(CFBundleGetFunctionPointerForName(sysBundle,
CFSTR("write")));
> ioctlp = reinterpret_cast_(IoctlProc)(CFBundleGetFunctionPointerForName(sysBundle,
CFSTR("ioctl")));
> tcdrainp = reinterpret_cast_(TcdrainProc)(CFBundleGetFunctionPointerForName(sysBundle,
CFSTR("tcdrain")));
> tcgetattrp = reinterpret_cast_(TcgetattrProc)(CFBundleGetFunctionPointerForName(sysBundle,
CFSTR("tcgetattr")));
> tcsetattrp = reinterpret_cast_(TcsetattrProc)(CFBundleGetFunctionPointerForName(sysBundle,
CFSTR("tcsetattr")));
> cfsetspeedp = reinterpret_cast_(CfsetspeedProc)(CFBundleGetFunctionPointerForName(sysBundle,
CFSTR("cfsetspeed")));
> cfmakerawp = reinterpret_cast_(CfmakerawProc)(CFBundleGetFunctionPointerForName(sysBundle,
CFSTR("cfmakeraw")));
> mach_thread_selfp = reinterpret_cast_(MachThreadSelfProc)(CFBundleGetFunctionPointerForName(sysBundle,
CFSTR("mach_thread_self")));
> sysctlp = reinterpret_cast_(SysctlProc)(CFBundleGetFunctionPointerForName(sysBundle,
CFSTR("sysctl")));
> }
> }
[quoted text clipped - 5 lines]
> while CRMSearch() correctly enumerates the ports under Classic, it returns
> 0 ports when called from Carbon this way. Does anyone have a solution?
David Phillip Oster - 27 Jan 2004 05:28 GMT
In article
<boardhead62-2601042154300001@kin-on50-055.dial.allstream.net>,
> HOOORAY!!!
>
[quoted text clipped - 28 lines]
> int num = sReadProc(mFileDescriptor, buff, 10);
> --------
should be:
typedef int (*ErrnoProc)(void);
typedef int (*OpenProc)(const char *path, int flags);
typedef int (*CloseProc)(int);
typedef int (*FcntlProc)(int fd, int cmd, int arg);
typedef int (*ReadProc)(int d, void *buf, size_t nbytes);
typedef int (*WriteProc)(int d, const void *buf, size_t nbytes);
typedef int (*IoctlProc)(int d, unsigned long request, char *argp);
typedef int (*TcdrainProc)(int fd);
typedef int (*TcgetattrProc)(int fd, struct termios *t);
typedef int (*TcsetattrProc)(int fd, int action, const struct termios *t);
typedef int (*CfsetspeedProc)(struct termios *t, speed_t speed);
typedef void (*CfmakerawProc)(struct termios *t);
typedef kern_return_t (*IOMasterPortProc)( mach_port_t bootstrapPort, mach_port_t *masterPort);
// and this works for me. (You don't have CarbonSerialPortX. deal.)
OSStatus ReadCarbonSerialPortX(CarbonSerialPortX* inP, long *ioLen, void *outBuffer){
int val;
if(-1 == (val = (*readp)(inP->refNum, outBuffer, *ioLen))){
if (0 != (*errnop)() ){
return (*errnop)();
}else{
return val;
}
}
*ioLen = val;
return noErr;
}
OSStatus GetUnreadCountCarbonSerialPortX(CarbonSerialPortX* inP, long *outCount){
int val, count;
if(-1 == (val = (*ioctlp)(inP->refNum, FIONREAD, (char*) &count))){
if (0 != (*errnop)() ){
return (*errnop)();
}else{
return val;
}
}
*outCount = count;
return noErr;
}
OSStatus WriteCarbonSerialPortX(CarbonSerialPortX* inP, long *ioLen, const void *inBuffer){
int val;
if(-1 == (val = (*writep)(inP->refNum, inBuffer, *ioLen))){
if (0 != (*errnop)() ){
return (*errnop)();
}else{
return val;
}
}
*ioLen = val;
return noErr;
}

Signature
David Phillip Oster
The Berkeley Developers' Group (a free, public, gathering of programmers)
meets every other Wednesday Night, starting around 7:10 pm in the back room
of The Original Burger (formerly Mel's) 2240 Shattuck Ave - at Kittredge
Street, Berkeley, CA. Next meeting is Jan 28, 2004
Phil - 27 Jan 2004 15:58 GMT
Thanks for helping me narrow down my problem. I took all the 'pascal's
out of my typedef's but that didn't change anything.
Other than that, the only difference was with ErrnoProc, which I have
returning an int* while you have int. This is odd because it works the
way I have it.
At any rate, my read() still returns an error. It must be in the way I'm
opening or setting up the port, because this is the only thing left. I've
simplified my code to the following self-contained segment to demonstrate
my problem:
--------
char buff[16];
int err = 0;
struct termios options;
int fd = sOpenProc("/dev/cu.modem", O_RDWR | O_NONBLOCK);
if (sTcgetattrProc(fd, &options) == -1) err = -1;
sCfmakerawProc(&options); // use raw i/o
sCfsetspeedProc(&options, 19200);
options.c_cflag = (CLOCAL | CREAD | CS8);
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
options.c_iflag |= (IXON | IXOFF);
options.c_oflag &= ~OPOST;
options.c_cc[ VMIN ] = 0;
options.c_cc[ VTIME ] = 0;
if (sTcsetattrProc(fd, TCSANOW, &options) == -1) err = -1;
int num = sReadProc(fd, buff, 1);
int readerr = *sErrnoProc();
--------
Does this look OK? I want to the port for a raw data stream with 19200
baud, 8 data bits, no parity, 1 stop bit, and XON/XOFF flow control.
After the code executes, the variables have the following values:
err = 0
fd = 13
num = -1
readerr = 9
Do you have any idea what the problem could be?
Once again, thanks for your generous help! (And your code examples are
invaluable! With your last post I learned how to use ioctl to get the
number of unread bytes, which I hadn't figured out how to do yet.)
I think I'm just one step away from having this working now!
- Phil
> In article
> <boardhead62-2601042154300001@kin-on50-055.dial.allstream.net>,
[quoted text clipped - 53 lines]
> return noErr;
> }
David Phillip Oster - 29 Jan 2004 07:50 GMT
> After the code executes, the variables have the following values:
>
> err = 0
> fd = 13
> num = -1
> readerr = 9
errno.h has this to say about that:
#define EBADF 9 /* Bad file descriptor */
Phil - 01 Feb 2004 00:14 GMT
The file discriptor is fine. I've been over it a thousand times and I
still can't get it to work. I can use the same file descriptor in a call
to write() with no problems.
Absolutely everything works great, but read() always returns an error.
The same code works fine when compiled as standalone with g++ (by calling
the functions directly instead of via the proc pointers). However read()
always returns an error when I call it via pointer from my CFM app.
It's like the wrong read function is being called. So I tried changing my
read() calls to readv(), but readv() has the same problem. I still
haven't ruled out a library problem though.
I'm lost. It looks like the end for me.
Phil - 28 Jan 2004 02:00 GMT
I've been trying everything I can think of since my last post, and I'm
convinced that it isn't in the way I open or configure the port since I've
tried just about every possible combination of values (including the
standard ones from the IOKit example).
However, in an act of utter despiration I tried calling just read()
instead of the read in the System Framework (which I access via my
ReadProc pointer), AND IT DIDN'T RETURN AN ERROR!!! However, it reads
utter garbage and the data doesn't even seem related to the serial data I
am receiving. (Not even like what I would expect if I just had the baud
rate wrong or something.) So I think this may not help but I thought I'd
mention it just in case.
So I still can't get the call to sReadProc() to work. I've tried it on 2
different Macs, both running OSX 10.2.8. I've tried it on every port of
my Keyspan Serial Pro card (with the most recent drivers). Nothing works.
The rest of the code works great, and even properly detects when there are
characters waiting in the receive buffer (using IoctlProc). But always
that darn error with ReadProc.
Again I am at a dead end.
Any help could be a life saver!
Thanks in advance.