2011-09-30 97 views
7

我使用获得连接串行电缆将我的iPhone串行编程附件连接到我的越狱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开发让更多的困惑。

谢谢

+0

我完全不了解jb iPhone上的编码级别。但是一些unix类型的检查可能会启发其他人。在/dev/tty.iap上有什么权限,并且用户是否拥有该设备的权限(尽管我猜你正在以ssh的身份运行代码?)。 – Diziet

+0

@Raj您是如何查看printf语句的输出的?很明显,控制台窗口是Xcode将无法正常工作,因为您的iDevice已连接到您的串行设备使用自定义的基座连接器,我认为? – Chris

回答

2

也许下面的文章iPhone串口通信可能有帮助吗?

iPhone/iPod Touch Serial Port Tutorial通过科林梅耶

iPhone Serial Communication

+0

我成功通过串口通讯将jb iPhone连接到配件,但我面临iPhone 4g的一个问题。每当我尝试将附件连接到iPhoen4g时,我都会收到一个错误“串行连接失败”。它的工作很好,3g或3g – Raj

+0

@Raj好吧,那么你应该更新你的原始问题,以反映那。 – fuzz

+0

@Fulvio,第二个链接有答案,至少在我的情况下。 +1(就是前一阵子)。 – newenglander

0

我尝试打开一个越狱的iPod Touch串口使用和Xcode创建一个二进制运行iOS 5.0时,得到了同样的错误。但是,当我在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)的限制,从串口读取 - - 不管这些限制可能是什么。