1

现在我得到了以下课程,但它不起作用。它在open通话中失败。我认为这是因为沙盒,但我不确定如何前进。这看起来也像 C 一样,有没有更好的 Objective-C (IOKIT?) 方法来解决这个问题?

设备本身是一个 USB 串行端口。

给出的错误:

打开设备失败:不允许操作

当前代码:

#include <termios.h>
#import "Com.h"

#define BAUDCOUNT 17
speed_t baud_const[BAUDCOUNT] = { B50,    B75,    B110,   B134,   B150,   B200,
                                  B300,   B600,   B1200,  B1800,  B2400,  B4800, 
                                  B9600,  B19200, B38400, B57600, B115200 };
unsigned long baud_value[BAUDCOUNT] = { 50,   75,    110,   134,   150,   200,
                                        300,  600,   1200,  1800,  2400,  4800, 
                                        9600, 19200, 38400, 57600, 115200 };

@interface Com()
@property (assign) int fd;
@property (assign) struct termios oldio;
@end


@implementation Com
@synthesize fd = _fd;
@synthesize oldio = _oldio;

- (id)init
{
    self = [super init];
    if (self)
    {
        self.fd = -1;
        return self;
    }
    return nil;
}

- (BOOL)open:(NSString*)device withBaud:(int)baud
{
    struct termios oldio;
    struct termios newtio;

    // Find the correct baud rate
    int baudid = -1;
    for(int i = 0; i < BAUDCOUNT; i++) {
        if (baud_value[i] == baud) {
            baudid = i;
            break;
        }
    }
    if(baudid == -1)
    {
        NSLog(@"Invlaid baud rate: %d", baud);
        return NO;
    }

    // Open the device
    self.fd = open([device UTF8String], O_RDWR | O_NOCTTY | O_NDELAY);
    if (self.fd < 0)
    {
        NSLog(@"Failed to open device: %s", strerror(errno));
        return NO;
    }

    // Save old settings
    tcgetattr(self.fd, &oldio);
    self.oldio = oldio;

    // Init memory
    memset(&newtio, 0x00 , sizeof(newtio));
    cfmakeraw(&newtio);

    // settings flags
    newtio.c_cflag |= CS8;
    newtio.c_cflag |= CLOCAL;
    newtio.c_cflag |= CREAD;
    newtio.c_iflag = IGNPAR | IGNBRK;
    newtio.c_oflag = 0;
    newtio.c_lflag = 0;

    // Timeout in 100ms
    newtio.c_cc[VTIME] = 0;
    // read 1 character
    newtio.c_cc[VMIN] = 0;

    // Setting baudrate
    cfsetispeed (&newtio, baud_const[baudid]);
    cfsetospeed (&newtio, baud_const[baudid]);

    // Flushing buffer
    tcflush(self.fd, TCIOFLUSH);

    // aplying new configuration
    tcsetattr(self.fd, TCSANOW, &newtio);

    return YES;
}
@end

当前权利:

<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.device.usb</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
4

2 回答 2

1

有几个用于处理串行端口的 Objective C 框架。

更新:在我看来,您可能需要该com.apple.security.device.serial权利。尽管您使用的是 USB 串行适配器,但我相信操作系统设备驱动程序使所有串行端口看起来都相同,即不是 USB 设备。我怀疑com.apple.security.device.usb您所拥有的权利不适用于 USB 串行设备。

更新 2:我刚刚从去年 8 月发现了这个Open Radar ,它报告了您的问题。因此,该com.apple.security.device.serial权利似乎不起作用(或者肯定在 8 月没有起作用)。

更新 3:如果您确实需要直接访问 USB 设备(并假设这适用于com.apple.security.device.usb权利),那么您可能需要查看http://opensource.apple.com/source/IOSerialFamily上提供的 IOSerialFamily 源代码/IOSerialFamily-59/

源码压缩包:http: //opensource.apple.com/tarballs/IOSerialFamily/IOSerialFamily-59.tar.gz

于 2012-04-17T03:30:42.993 回答
0

您正在做一些内核编程,这可能是您想要做的,但如果您可以使用 IOKit,那么我建议您这样做。简而言之,我不建议您使用内核 + 沙盒进行任何操作。

IOKit 是另一种类型的动物,确实还不错。这是一个带有快速片段的示例,它将禁用系统睡眠。这演示了如何使用 IOKit,我相信它确实适用于沙盒应用程序。

    IOPMAssertionID assertionID;
    IOReturn err = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, CFSTR("Add Reason Here"), &assertionID);
    if ( err == kIOReturnSuccess ) {

        // Do stuff here while system is unable to sleep

        // Let the system resume ability to sleep
        err = IOPMAssertionRelease(assertionID);
    }

该文档也应该有所帮助:链接

注意:“重要如果您的应用程序是沙盒的,它必须请求 com.apple.security.device.usb 授权才能访问 USB 设备。”

于 2012-04-17T05:38:09.487 回答