1

現在、次のクラスを取得しましたが、機能していません。呼び出しで失敗しopenます。これはサンドボックス化が原因だと思いますが、どうすればよいかわかりません。また、これは ver 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

シリアル ポートを処理する目的の C フレームワークがいくつかあります。

更新:com.apple.security.device.serial資格が必要なようです。USB シリアル アダプタを使用しているという事実にもかかわらず、OS デバイス ドライバにより、すべてのシリアル ポートが同じように、つまり USB デバイスではないように見えると思います。あなたが持っているcom.apple.security.device.usb資格は、USB シリアル デバイスには適用されないのではないかと思います。

更新 2:昨年 8 月にこのOpen Radarを見つけたところ、あなたの問題が報告されています。そのため、com.apple.security.device.serial資格が機能していないようです (または、8 月には機能しなかったことは確かです)。

更新 3: USB デバイスに直接アクセスする必要がある場合 (およびこれがエンタイトルメントで機能すると仮定した場合) は、おそらくhttp://opensource.apple.com/source/IOSerialFamilycom.apple.security.device.usbで入手できる IOSerialFamily ソース コードを確認することをお勧めします。 /IOSerialFamily-59/ .

ソース tarball: 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);
    }

このドキュメントも役立ちます:リンク

注:「重要アプリケーションがサンドボックス化されている場合、USBデバイスにアクセスするには、com.apple.security.device.usbエンタイトルメントを要求する必要があります。」

于 2012-04-17T05:38:09.487 に答える