【问题标题】:Connect the Accessory to my JailBreak iPhone Device将附件连接到我的 JailBreak iPhone 设备
【发布时间】:2011-11-28 07:26:53
【问题描述】:

我正在使用串行编程将串行电缆连接到我的 iPhone

我的代码如下

#include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <errno.h>   /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */

static struct termios gOriginalTTYAttrs;

static int OpenSerialPort()
{
    int        fileDescriptor = -1;
    int        handshake;
    struct termios  options;

    // Open the serial port read/write, with no controlling terminal, and don't wait for a connection.
    // The O_NONBLOCK flag also causes subsequent I/O on the device to be non-blocking.
    // See open(2) ("man 2 open") for details.

    fileDescriptor = open("/dev/tty.iap", O_RDWR | O_NOCTTY | O_NONBLOCK);
    if (fileDescriptor == -1)
    {
        printf("Error opening serial port %s - %s(%d).\n",
               "/dev/tty.iap", strerror(errno), errno);
        goto error;
    }

    // Note that open() follows POSIX semantics: multiple open() calls to the same file will succeed
    // unless the TIOCEXCL ioctl is issued. This will prevent additional opens except by root-owned
    // processes.
    // See tty(4) ("man 4 tty") and ioctl(2) ("man 2 ioctl") for details.

    if (ioctl(fileDescriptor, TIOCEXCL) == -1)
    {
        printf("Error setting TIOCEXCL on %s - %s(%d).\n",
            "/dev/tty.iap", strerror(errno), errno);
        goto error;
    }

    // Now that the device is open, clear the O_NONBLOCK flag so subsequent I/O will block.
    // See fcntl(2) ("man 2 fcntl") for details.

    if (fcntl(fileDescriptor, F_SETFL, 0) == -1)
    {
        printf("Error clearing O_NONBLOCK %s - %s(%d).\n",
            "/dev/tty.iap", strerror(errno), errno);
        goto error;
    }

    // Get the current options and save them so we can restore the default settings later.
    if (tcgetattr(fileDescriptor, &gOriginalTTYAttrs) == -1)
    {
        printf("Error getting tty attributes %s - %s(%d).\n",
            "/dev/tty.iap", strerror(errno), errno);
        goto error;
    }

    // The serial port attributes such as timeouts and baud rate are set by modifying the termios
    // structure and then calling tcsetattr() to cause the changes to take effect. Note that the
    // changes will not become effective without the tcsetattr() call.
    // See tcsetattr(4) ("man 4 tcsetattr") for details.

    options = gOriginalTTYAttrs;

    // Print the current input and output baud rates.
    // See tcsetattr(4) ("man 4 tcsetattr") for details.

    printf("Current input baud rate is %d\n", (int) cfgetispeed(&options));
    printf("Current output baud rate is %d\n", (int) cfgetospeed(&options));

    // Set raw input (non-canonical) mode, with reads blocking until either a single character 
    // has been received or a one second timeout expires.
    // See tcsetattr(4) ("man 4 tcsetattr") and termios(4) ("man 4 termios") for details.

    cfmakeraw(&options);
    options.c_cc[VMIN] = 1;
    options.c_cc[VTIME] = 10;

    // The baud rate, word length, and handshake options can be set as follows:

    cfsetspeed(&options, B19200);    // Set 19200 baud    
    options.c_cflag |= (CS8);  // RTS flow control of input


    printf("Input baud rate changed to %d\n", (int) cfgetispeed(&options));
    printf("Output baud rate changed to %d\n", (int) cfgetospeed(&options));

    // Cause the new options to take effect immediately.
    if (tcsetattr(fileDescriptor, TCSANOW, &options) == -1)
    {
        printf("Error setting tty attributes %s - %s(%d).\n",
            "/dev/tty.iap", strerror(errno), errno);
        goto error;
    }    
    // Success
    return fileDescriptor;

    // Failure "/dev/tty.iap"
error:
    if (fileDescriptor != -1)
    {
        close(fileDescriptor);
    }

    return -1;
}

int main(int args, char *argv[])
{
    int fd;
    char somechar[8];
    fd=OpenSerialPort(); // Open tty.iap with no hardware control, 8 bit, BLOCKING and at 19200 baud
    if(fd>-1)
    {
        write(fd,"*",1); // Write handshaking message over serial
        ///////////////////////////////////////////////////////////////////////////////////////////////////
        // After this, our device or our PC program should be strobing serial ground to gain access to the Iphone Serial Line
        //////////////////////////////////////////////////////////////////////////////////////////////////
        read(fd,&somechar[0],1); // Read 1 byte  over serial.  This will block (wait) untill the byte has been received
        if(somechar[0]=='*') // Check if this byte is a "handshaking" message
        {
            printf("Serial connection established!\n"); // If it is, we have established a connection to the device and can freely read/write over serial!
            while(1) // Do this forever or untill someone presses CTRL+C
            {
                read(fd,&somechar[0],1);  // Read a character over serial!
                putchar(somechar[0]); // Write the character to the Terminal!!
            }
        }
    }
    return 0;
}

但是当我要检查电缆是否连接时,我遇到了这样的错误

打开串行端口 /dev/tty.iap 时出错 - 不允许操作 (1)。

有没有人知道解决方案,如果我走错路,请给我建议 实际上我是 iOS 开发的新手,所以比较困惑。

谢谢

【问题讨论】:

  • 我完全不熟悉 jb iPhone 上的那种编码水平。然而,一些 unix 类型检查可能会启发其他人。 /dev/tty.iap 上有哪些权限,您运行代码的用户是否对设备具有权限(尽管我猜您是以 root 身份运行代码 ssh 的?)。
  • @Raj 您如何查看 printf 语句的输出?显然控制台窗口是 Xcode 将无法工作,因为您的 iDevice 使用我认为的自定义扩展坞连接器连接到您的串行设备?

标签: iphone ipad serial-communication external-accessory


【解决方案1】:

也许以下文章 iPhone 串行通信可能会有所帮助?

iPhone/iPod Touch Serial Port Tutorial科林·迈耶

iPhone Serial Communication

【讨论】:

  • 我成功地通过串行通信将 jb iPhone 与配件通信,但我在 iPhone 4g 上遇到了一个问题。每当我尝试将该配件连接到 iPhoen4g 时,我都会收到一个错误“串行连接失败”。它在 3g 或 3gs 下工作正常
  • @Raj 好的,那么您应该更新您的原始问题以反映这一点。
  • @Fulvio,第二个链接有答案,至少在我的情况下。为此 +1(不久前)。
  • @newenglander 没问题。很高兴为您提供帮助。
【解决方案2】:

我在尝试使用 Xcode 创建的二进制文件打开运行 iOS 5.0 的越狱 iPod Touch 上的串行端口时遇到了同样的错误。但是,当我在 Mac 上的命令行上使用 gcc(对于设置了适当标志的 iPhone)而不是 Xcode 并为 iOS 创建了一个命令行应用程序时,生成的二进制文件能够打开串行端口并读取命令从我的外部配件。 这应该可以创建一个库并将其与 Xcode 链接并具有相同的结果(尽管我还没有尝试过)。

更新:不幸的是,在 gcc 中创建库并将其链接到 Xcode 项目中遇到了与以前相同的错误。可能的解决方案:

  • 从 iOS Xcode GUI 应用程序调用命令行应用程序
  • 使用 gcc 而不是 Xcode 编译应用程序本身

实际上,它甚至比这更简单,在 Fulvio 的回答中通过第二个link 时发现它:您只需将应用程序移动到与 Xcode 通常放置它们的位置不同的目录即可。按照博客文章中的建议,我将我的应用程序放在 Cydia 应用程序目录 (/private/var/stash/Applications) 中,并且能够打开串行端口 - 无需 gcc 编译。

所以我的gcc-compiled 命令行应用程序能够从串口读取,因为我在根目录的主目录中执行它,它也没有普通应用程序目录的限制(/private/var/mobile/Applications )——无论这些限制是什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-10
    • 2015-02-12
    • 2023-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多