Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Responses with newlines #132

Open
bgueth opened this issue Jan 22, 2019 · 1 comment
Open

Responses with newlines #132

bgueth opened this issue Jan 22, 2019 · 1 comment
Assignees
Labels

Comments

@bgueth
Copy link

bgueth commented Jan 22, 2019

I got a device which sends upon a request things like this:

     0; 18.10.13; 10:40:24;        2; 00:51:33;      150;     2804;     1465;        2.96;       -7.87;       14.72;Bernhard Gueth  ;Advance Alpha 5 ;not-set     \r\n         
     1; 18.10.12; 11:35:32;        2; 01:54:59;      132;     2845;      644;        5.63;       -6.31;       16.37;Bernhard Gueth  ;Advance Alpha 5 ;not-set     \r\n
Done\r\n

Every line is 168 bytes long. If I send a request to the device using the following code

func sendCommand(_ : String) {

        let commandString = String("ACT_20_00\r\n");
        let command = commandString.data(using: .ascii)!
        let responseExp = try? NSRegularExpression(pattern: "(.{166}\r\n)*Done\r\n", options: .caseInsensitive)
        let responseDescriptor = ORSSerialPacketDescriptor(regularExpression: responseExp!, maximumPacketLength: 1024, userInfo: nil)
        let request = ORSSerialRequest(
            dataToSend: command,
            userInfo: FlytecRequestType.readFlightbook.rawValue,
            timeoutInterval: 1.5,
            responseDescriptor: responseDescriptor)
        self.serialPort?.send(request)
}

I'd expect it to read the all the lines. However, when i inspect the response

func serialPort(_ serialPort: ORSSerialPort, didReceiveResponse responseData: Data, to request: ORSSerialRequest) {
        guard let receivedString = String(data: responseData, encoding: .ascii) else {
            return
        }
        print(receivedString)
}

I only get the last line ("Done\r\n") but not the other ones. I fiddled out, that it seems, that responses are broken up when a newline is read from the device. Is there any way to work around this?

With best regards

Bernhard

@armadsen armadsen self-assigned this Feb 7, 2019
@armadsen
Copy link
Owner

armadsen commented Feb 7, 2019

Hi Bernhard, I'd have to dig into this with some tests. I would think what you've got should work. Not sure why it's not. I wonder what happens if you try:

func sendCommand(_ string: String) {

    let commandString = "ACT_20_00\r\n"
    let command = commandString.data(using: .ascii)!
    let responseDescriptor = ORSSerialPacketDescriptor(maximumPacketLength: 169, userInfo: nil) { (data) -> Bool in
        guard let string = data.flatMap({ String(data: $0, encoding: .ascii) }) else { return false }
        return string.count >= 168 && string.hasSuffix("\n")
    }
    let request = ORSSerialRequest(
        dataToSend: command,
        userInfo: FlytecRequestType.readFlightbook.rawValue,
        timeoutInterval: 1.5,
        responseDescriptor: responseDescriptor)
    self.serialPort?.send(request)
}

Here, instead of relying on the RegEx to work, I explicitly check the length and end delimiter for the incoming packet. The caveat here is that you won't get the "Done\r\n" because of the length requirement, but if you need that, you could of course special case it in the packet evaluator closure.

(Incidentally, this will become easier when I implement #89.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants