代码之家  ›  专栏  ›  技术社区  ›  Brandon

读取串行端口IOS

  •  10
  • Brandon  · 技术社区  · 6 年前

    我有以下代码读写到iOS 10.3.3越狱iPhone 6S上的串行端口(我使用H3lix越狱):

    序列号H:

    //
    //  Serial.h
    //  iOUSB
    //
    //  Created by Brandon on 2018-05-21.
    //  Copyright © 2018 XIO. All rights reserved.
    //
    
    #if !defined(__cplusplus)  //-fmodules -fcxx-modules
    @import Foundation;
    #else
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wauto-import"
    #import <Foundation/Foundation.h>
    #pragma clang diagnostic pop
    #endif
    
    #define BAUD_RATE 9600
    
    @interface Serial : NSObject
    + (instancetype)shared;
    - (bool)setup:(NSString *)filePath;
    - (bool)disconnect;
    - (size_t)available;
    - (size_t)read:(uint8_t *)bytes length:(int32_t)length;
    - (size_t)write:(uint8_t *)bytes length:(int32_t)length;
    - (void)flushInputStream;
    - (void)flushOutputStream;
    - (void)flush;
    - (NSString *)lastError;
    - (void)eraseLastError;
    @end
    

    序列号.mm:

    //
    //  Serial.mm
    //  iOUSB
    //
    //  Created by Brandon on 2018-05-21.
    //  Copyright © 2018 XIO. All rights reserved.
    //
    
    #import "Serial.h"
    #include <fstream>
    #include <iostream>
    #include <sys/fcntl.h>
    #include <sys/stat.h>
    #include <sys/ioctl.h>
    #include <termios.h>
    #include <unistd.h>
    
    #define DEFAULT_BAUD_RATE 9600
    
    @interface Serial()
    @property (nonatomic, assign) int file_descriptor;
    @property (nonatomic, strong) NSString *lastError;
    @end
    
    @implementation Serial
    + (instancetype)shared {
        static Serial *instance;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            instance = [[Serial alloc] init];
        });
        return instance;
    }
    
    - (instancetype)init {
        if ((self = [super init])) {
            self.file_descriptor = -1;
            self.lastError = nil;
        }
        return self;
    }
    
    - (void)dealloc {
        [self disconnect];
    }
    
    - (bool)setup:(NSString *)filePath {
        if (self.file_descriptor != -1)
        {
            return true;
        }
    
        self.file_descriptor = open(filePath.UTF8String, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
        if (self.file_descriptor == -1)
        {
            const char* error = strerror(errno);
            self.lastError = [[NSString alloc] initWithUTF8String:error];
            perror(error);
            return false;
        }
    
        struct termios options;
        struct termios oldoptions;
        tcgetattr(self.file_descriptor, &oldoptions);
        options = oldoptions;
    
        #if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
        int baud_rates[] = {B0, B50, B75, B110, B134, B150, B200, B300, B1200, B1800, B2400, B4800, B9600, B19200, B38400, B7200, B14400, B28800, B57600, B76800, B115200, B230400
        };
        #else
        int baud_rates[] = {B0, B50, B75, B110, B134, B150, B200, B300, B1200, B1800, B2400, B4800, B9600, B19200, B38400};
        #endif
    
        auto it = std::find(std::begin(baud_rates), std::end(baud_rates), BAUD_RATE);
        if (it != std::end(baud_rates))
        {
            cfsetispeed(&options, *it);
            cfsetospeed(&options, *it);
            std::cout<<"BAUD_RATE Set Successfully!\n";
        }
        else
        {
            cfsetispeed(&options, DEFAULT_BAUD_RATE);
            cfsetospeed(&options, DEFAULT_BAUD_RATE);
            std::cerr<<"Invalid BAUD_RATE.. Setting to default: "<<DEFAULT_BAUD_RATE<<"\n";
        }
    
        options.c_cflag |= (CLOCAL | CREAD);
        options.c_cflag |= CS8;
        options.c_cflag &= ~PARENB;
        options.c_cflag &= ~CSTOPB;
        options.c_cflag &= ~CSIZE;
        tcsetattr(self.file_descriptor, TCSANOW, &options);
        return true;
    }
    
    - (bool)disconnect {
        if (self.file_descriptor != -1)
        {
            close(self.file_descriptor);
            self.file_descriptor = -1;
            self.lastError = nil;
        }
    
        return self.file_descriptor == -1;
    }
    
    - (size_t)available {
        if (self.file_descriptor == -1)
        {
            return -1;
        }
    
        int available = -1;
        ioctl(self.file_descriptor, FIONREAD, &available);
        return available;
    }
    
    - (size_t)read:(uint8_t *)bytes length:(int32_t)length {
        if (self.file_descriptor == -1)
        {
            return -1;
        }
    
        ssize_t bytesRead = read(self.file_descriptor, bytes, length);
        if (bytesRead < 0)
        {
            const char* error = strerror(errno);
            self.lastError = [[NSString alloc] initWithUTF8String:error];
            perror(error);
        }
        return bytesRead;
    }
    
    - (size_t)write:(uint8_t *)bytes length:(int32_t)length {
        if (self.file_descriptor == -1)
        {
            return -1;
        }
    
        ssize_t bytesWritten = write(self.file_descriptor, bytes, length);
        if (bytesWritten <= 0)
        {
            const char* error = strerror(errno);
            self.lastError = [[NSString alloc] initWithUTF8String:error];
            perror(error);
        }
        return bytesWritten;
    }
    
    - (void)flushInputStream {
        if (self.file_descriptor == -1)
        {
            return;
        }
    
        tcflush(self.file_descriptor, TCIFLUSH);
    }
    
    - (void)flushOutputStream {
        if (self.file_descriptor == -1)
        {
            return;
        }
    
        tcflush(self.file_descriptor, TCOFLUSH);
    }
    
    - (void)flush {
        if (self.file_descriptor == -1)
        {
            return;
        }
    
        tcflush(self.file_descriptor, TCIOFLUSH);
    }
    
    - (NSString *)lastError {
        return _lastError ?: @"";
    }
    
    - (void)eraseLastError {
        _lastError = nil;
    }
    @end
    

    我购买了OTG适配器:“Lightning to USB 3 Camera Adapter”,如图所示: https://www.apple.com/ca/shop/product/MK0W2AM/A/lightning-to-usb-3-camera-adapter

    我已经插入设备,它显示为不受支持的设备,这是好的,因为它没有MFI认证。

    但是,当我试图打开 /dev/tty.iap ,我不断地 Error: Resource Busy .

    我能打开 /dev/tty.wlan 例如。。只有一些港口给我这样的麻烦 iap 一个。

    我做了什么我看不懂的错事 tty.iap ?我尝试将应用程序作为根目录运行,方法是将其移动到 /Applications /var/containers/Bundle/Applications …我试过了 chown root:wheel 应用程序和 chmod 0777 应用程序。我还是明白了 resource busy

    我在网上看到,当你不是根用户的时候,你会得到这个错误。

    如何以根用户身份运行应用程序? 我怎样才能修复这个以便能读取闪电端口?

    我试过了 https://stackoverflow.com/a/15970080/1462718 但它似乎不起作用。无论我尝试了多少次,应用程序都会启动,然后立即关闭。

    1 回复  |  直到 6 年前
        1
  •  3
  •   Tiago Peres damanpreet singh    6 年前

    默认情况下,串行端口用作带外管理接口(允许您在网络关闭时通过串行连接连接到系统)。

    在将串行端口重新用于任何其他用途之前,需要禁用此功能。

    如何做到这一点的具体细节因操作系统版本而异。