OBDKey(inputStream)的反应不当

时间:2014-04-23 18:22:07

标签: ios objective-c inputstream obd-ii

我目前正在开发一个关于iPhone和OBDKey之间通过wifi进行通信的iPhone应用程序。 到现在为止还挺好。我设法使用CFStream建立TCP / IP通信。 我现在的问题是:当我向OBDKey发送一些消息时,响应是完全相同的消息。

我认为错误代码位于应用程序的流方法中。但我无法弄清楚。

我希望你能给我一些建议。

以下是代码:

CFReadStreamRef readStream;
CFWriteStreamRef writeStream;

NSInputStream *inputStream;
NSOutputStream *outputStream;

@implementation Communicator
@synthesize textField; //Gegenstück zu @property im .h File
@synthesize textView;  //Gegenstück zu @property im .h File


- (IBAction)connectPressed:(id)sender {

    host = @"192.168.0.74";
    port = 23;

    //Ausgabe
    [self debugPrint:[NSString stringWithFormat:@"Setting up connection to %@ : %i", host, port]];

    //Stream wird erzeugt mit Host, Port, Read & Write stream
    CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault,  (__bridge CFStringRef)(host), port, &readStream, &writeStream);


    //Überprüfung ob Write Stream funktioniert
    if (!CFWriteStreamOpen(writeStream))     {

        [self debugPrint:[NSString stringWithFormat:@"Error, writeStream not open"]];

        return;
    }


    //Methode open wird geöffnet
    [self open];

    [self debugPrint:[NSString stringWithFormat:@"Status of outputStream: %i", [outputStream streamStatus]]];

    return;
}

//Hier werden sowohl der Output(Write)- als auch der Input(Read)-Stream geöffnet.
- (void)open {

    [self debugPrint:[NSString stringWithFormat:@"Opening streams..."]];

    //Da Automatic Reference Counting betrieben wird, muss eine __bridge Notation gesetzt werden um
    //das Objekt hin und her verwenden zu können.
    inputStream = (__bridge NSInputStream *)readStream;
    outputStream = (__bridge NSOutputStream *)writeStream;

    [inputStream setDelegate:self];
    [outputStream setDelegate:self];

    //RunLoop wird verwendet um input und output Objekte zu managen (Reihenfolgen usw.)
    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];



    [inputStream open];
    [outputStream open];

    //Überprüfung ob beide Streams geöffnet wurden
    if (!inputStream && !outputStream)
    {
        [self debugPrint:[NSString stringWithFormat:@"Error. Could not open streams!"]];

        return;
    }

    //[self debugPrint:[NSString stringWithFormat:@"Streams are open"]];


}

//Disconnect Button wird gedrückt - Hierbei werden alle input und output streams geschlossen
//und RunLoops geschlossen
- (IBAction)disconnectPressed:(id)sender {

    [inputStream close];
    [outputStream close];

    [inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

    [inputStream setDelegate:nil];
    [outputStream setDelegate:nil];

    inputStream = nil;
    outputStream = nil;


    [self debugPrint:[NSString stringWithFormat:@"Session closed!"]];


}

//Methode welche den eingegeben Text vom TextField in das TextView schreibt
- (IBAction)sendPressed:(id)sender {

    //Hier wird überprüft ob eine Eingabe im textField erfolgt ist (ob Zeichen eingegeben wurden)
    if ([[textField text] length] > 0) {
        NSString *textFieldString = [textField text];

        [self writeOut:(NSString *)textFieldString];

        [self.textField endEditing:YES];
    }

}

- (IBAction)clearViewPressed:(id)sender {

    textView.text = nil;

}

//Methode in der Text formatiert im textView angezeigt werden kann
- (void)debugPrint:(NSString *)text {
    textView.text = [textView.text stringByAppendingFormat: @"\n%@", text];
}

//Methode die Zuständig ist zum Stream handling
//NSStreamEventNone = 0
//NSStreamEventOpenCompleted = 1
//NSStreamHasBytesAvailable = 2
//NSStreamHasSpaceAvailable = 4
//NSStreamEventErrorOccurred = 8
//NSStreamEventEndEncountered = 16

- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)event {

    if (stream.streamStatus == 2){

    [self debugPrint:[NSString stringWithFormat:@"Stream opened"]];

    }

    switch (event) {

        case NSStreamEventHasSpaceAvailable: {
            if (stream == outputStream){
                [self debugPrint:[NSString stringWithFormat:@"Ouput stream is ready!"]];
            }
            break;
        }
        case NSStreamEventHasBytesAvailable: {
            if (stream == inputStream) {

            [self debugPrint:[NSString stringWithFormat:@"Input stream is ready!"]];

                uint8_t buf[1024];
                unsigned int len = 0; //len wird nie negativ sein => unsigned

                len = [inputStream read:buf maxLength:1024];

                if (len > 0) {

                    NSMutableData* data=[[NSMutableData alloc] initWithLength:0];

                    //data wird mit Daten aus dem Buffer buf gefüttert (maximale Länge len)
                    [data appendBytes: (const void *)buf length:len];

                    //Erlaubt die Konvertierung eines Datenstrings in einen Characterstring
                    NSString *raw_data = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];

                    //sends raw_data to readIn method
                    [self readIn:raw_data];


                }


            }
            break;

        }
        default: {

            [self debugPrint:[NSString stringWithFormat:@"Stream is sending an Event: %u", event]];
            break;
        }
    }
}


- (void)readIn:(NSString *)s {
    [self debugPrint:[NSString stringWithFormat:@"Reading:"]];
    [self debugPrint:[NSString stringWithFormat:@"%@",s]];
}

- (void)writeOut:(NSString *)string {

    uint8_t *buf = (uint8_t *)[string UTF8String];

    [outputStream write:buf maxLength:strlen((char *)buf)];
    [self debugPrint:[NSString stringWithFormat:@"%s\r\n",buf]];
    //[self debugPrint:[NSString stringWithFormat:@"Sent:"]];
    //[self debugPrint:[NSString stringWithFormat:@"%@\r\n",string]];
}

@end

提前谢谢!!!

编辑1:我已经使用Telnet(127.0.0.1:23)在我的Mac上使用终端应用程序尝试了我的代码。发送和接收都很完美。但是OBKey的响应与我发送的请求相同。

编辑2:我弄清楚了:我必须发送初始化握手命令以启动实际通信(ATZ,ATSP0和ATL1)。我已经在应用程序的连接过程中调用的单独方法中完成了此操作。

电贺, qoob

1 个答案:

答案 0 :(得分:0)

我没有进入ios应用程序,因此您可能需要仔细检查是否在单独声明输入/输出时没有做任何tyopo。您应该在1规则中使用输出流时使用输入流吗?

其他东西突然出现在我脑海中。对于有相同症状的人可能有用。我真的不能看到你收到的数据,但是因为你说你收到了你发送的数据,你的回声可以打开。

对于ELM327设备,您可以通过发送

关闭回声
E0