Responses with newlines
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
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.)