1

I want to read out the Vehicle Identification Number (VIN) of a car via an OBD WiFi Adapter. Pinging the adapter is possible and it got an fix IP Adress and Port.

Now i wanted to send the VIN-request on the Stream, but nothing happens.

My .h file

@interface Communicator : NSObject <NSStreamDelegate> {
@public

NSString *host;
int port;
}

- (void)setup;
- (void)open;
- (void)close;
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)event;
- (void)readIn:(NSString *)s;
- (void)writeOut:(NSString *)s;

@end

My .m file

#import "Communicator.h"

CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
NSInputStream *inputStream;
NSOutputStream *outputStream;

@implementation Communicator

- (void)setup {
NSURL *url = [NSURL URLWithString:host];

NSLog(@"Setting up connection to %@ : %i", [url absoluteString], port);

CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (__bridge CFStringRef)[url host], port, &readStream, &writeStream);

if(!CFWriteStreamOpen(writeStream)) {
    NSLog(@"Error, writeStream not open");
    return;
}
[self open];

NSLog(@"Status of outputStream: %i", [outputStream streamStatus]);
return;
}

- (void)open {
NSLog(@"Opening streams.");

inputStream = (__bridge NSInputStream *)readStream;
outputStream = (__bridge NSOutputStream *)writeStream;

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

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

[inputStream open];
[outputStream open];

if ([inputStream hasBytesAvailable])
{
    NSLog(@"We can recieve something from the InputStream");
}
if ([outputStream hasSpaceAvailable])
{
    NSLog(@"We can send something trough the OutputStream");
}

}

- (void)close {
NSLog(@"Closing streams.");
...
}

- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)event {
NSLog(@"Stream triggered.");

NSLog(@"event: %u", event);

switch(event) {
    case NSStreamEventHasSpaceAvailable: {
        if(stream == outputStream) {
            NSLog(@"outputStream is ready.");
        }
        break;
    }
    case NSStreamEventHasBytesAvailable: {
        if(stream == inputStream) {
            NSLog(@"inputStream is ready.");

            uint8_t buf[1024];
            unsigned int len = 0;

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

            if(len > 0) {
                NSMutableData* data=[[NSMutableData alloc] initWithLength:0];

                [data appendBytes: (const void *)buf length:len];

                NSString *s = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];

                [self readIn:s];

            }
        }
        break;
    }
    default: {
        NSLog(@"Stream is sending an Event: %i", event);

        break;
    }
}
}

- (void)readIn:(NSString *)s {
NSLog(@"Reading in the following:");
NSLog(@"%@", s);
}

- (void)writeOut:(NSString *)s {
uint8_t *buf = (uint8_t *)[s UTF8String];
[outputStream write:buf maxLength:strlen((char *)buf)];
NSLog(@"Status of outputStream: %i", [outputStream streamStatus]);

NSError *theError = [outputStream streamError];
NSLog(@"Error: %@", theError);

NSLog(@"Writing out the following:");
NSLog(@"%@", s);
}

@end 

my main

@autoreleasepool {

Communicator *c = [[Communicator alloc] init];

c->host = @"https://169.254.1.10";
//c->host = @"http://169.254.1.10";
//c->host = @"169.254.1.10";
c->port = 23;

[c setup];
[c open];

[c writeOut:@"0902"];

do {
} while (1);

         }
return 0;
}

console says this:

2012-12-13 16:22:41.319 obdlink[1940:f803] Setting up connection to https://169.254.1.10 : 23
2012-12-13 16:22:55.409 obdlink[1940:f803] Opening streams.
2012-12-13 16:23:16.504 obdlink[1940:f803] Status of outputStream: 1
2012-12-13 16:23:20.878 obdlink[1940:f803] Opening streams.
2012-12-13 16:23:33.858 obdlink[1940:f803] Status of outputStream: 2
2012-12-13 16:23:46.092 obdlink[1940:f803] Error: (null)
2012-12-13 16:23:59.011 obdlink[1940:f803] Writing out the following:
2012-12-13 16:24:01.104 obdlink[1940:f803] 0902

"0902" is the command that should return me a 5x5 multi-frame response with the VIN.

I really tried everything i could imagine or i found in the world wide web. Im stuck and dont know further, i hope anyone here can help me.

Hickey
  • 11
  • 2
  • At a wild guess, you need to send a CRLF at the end of the string to get a response. This is a telnet based protocol, so you should verify that it works by doing `telnet 169.254.1.10` and typing the commands at the `>` prompt. – Anya Shenanigans Dec 13 '12 at 19:13
  • @Petesh thx for your answer. Unfortunately the CRLF didnt help. There is still no response. But i can verify that it works with telnet and i got the expected results on the prompt. – Hickey Dec 14 '12 at 10:12
  • You may need to perform a proper telnet handshake in order to get the responses you're expecting. There is an attempt to implement the telnet connection in objective c in this answer - http://stackoverflow.com/questions/13477566/telnet-over-a-socket-with-gcdasyncsocket I don't know of any readily available (free) classes that will do this for you automatically, but implementing it is not difficult. – Anya Shenanigans Dec 14 '12 at 11:15
  • thx again for the link. Ill try that, but will take some time. Have only little time this weekend. Please go on watching this thread and responding that fast, it helps me a lot. Ill respond as fast as possible if i got some results. – Hickey Dec 16 '12 at 00:11
  • Sorry for the delay. Christmas time is interrupting my plans. I hope that i can look for your solution/guesses till end of week. Stay tuned. – Hickey Dec 19 '12 at 12:53
  • Instead of CRLF, try just CR ('\r' or hex 0D) at the end. – obdkey Dec 31 '12 at 16:12
  • Hey guys. Thx @obdkey u were right, a simple '\r' is enough. But it turns out that my handleEvent method is the problem. Wireshark tells me, that the request and the response is alright. My handleEvent Method isn't called. – Hickey Jan 28 '13 at 17:46

0 Answers0