Created
September 3, 2020 05:16
-
-
Save mlavergn/5a03b23e8a92115ad6b206cbcf865fa9 to your computer and use it in GitHub Desktop.
Swift socket
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// playing around with the Sharp Aquos protocol | |
import Foundation | |
enum Aquos: String { | |
case setup = "RSPW2 \r\n" | |
case powerOff = "POWR0 \r\n" | |
case powerOn = "POWR1 \r\n" | |
case channelUp = "CHUP0 \r" | |
case channelDown = "CHDW0 \r" | |
case ok = "OKR" | |
var string: String { | |
return self.rawValue | |
} | |
} | |
class Socket: NSObject, StreamDelegate { | |
var maxReadLength = 8192 | |
var inputStream: InputStream? = nil | |
var outputStream: OutputStream? = nil | |
var eventBlock: ((Stream.Event) -> Void)? | |
func connect(_ address: String, _ port: Int, _ eventBlock: ((Stream.Event) -> Void)?) -> Bool { | |
self.eventBlock = eventBlock | |
Stream.getStreamsToHost(withName: address, port: port, inputStream: &self.inputStream, outputStream: &self.outputStream) | |
guard let inputStream = inputStream, let outputStream = outputStream else { | |
return false | |
} | |
self.inputStream = inputStream | |
self.outputStream = outputStream | |
self.inputStream?.delegate = self | |
self.outputStream?.delegate = self | |
self.inputStream?.schedule(in: RunLoop.current, forMode: RunLoop.Mode.default) | |
self.outputStream?.schedule(in: RunLoop.current, forMode: RunLoop.Mode.default) | |
self.inputStream?.open() | |
self.outputStream?.open() | |
return true | |
} | |
func disconnect() { | |
if let inputStream = self.inputStream { | |
inputStream.close() | |
inputStream.remove(from: RunLoop.current, forMode: RunLoop.Mode.common) | |
self.inputStream = nil | |
} | |
if let outputStream = self.outputStream { | |
outputStream.close() | |
outputStream.remove(from: RunLoop.current, forMode: RunLoop.Mode.common) | |
self.outputStream = nil | |
} | |
} | |
func write(string: String) -> Int { | |
guard let data = string.data(using: .utf8) else { | |
print("Failed to convert String to Data") | |
return -1 | |
} | |
return self.write(data: data) | |
} | |
func write(data: Data) -> Int { | |
print("tx") | |
return data.withUnsafeBytes({ (unsafeBytes: UnsafeRawBufferPointer) -> Int in | |
guard let unsafePointer = unsafeBytes.bindMemory(to: UInt8.self).baseAddress else { | |
return -1 | |
} | |
let bytesWritten = self.outputStream?.write(unsafePointer, maxLength: data.count) | |
return bytesWritten ?? 0 | |
}) | |
} | |
func readAvailableBytes() -> Data { | |
print("rx") | |
var result = Data() | |
let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: maxReadLength) | |
while self.inputStream?.hasBytesAvailable ?? false { | |
let readLen = self.inputStream?.read(buffer, maxLength: self.maxReadLength) ?? -1 | |
if readLen < 0 { | |
if let error = self.inputStream?.streamError { | |
print(error) | |
break | |
} | |
} else if readLen > 0 { | |
result.append(buffer, count: readLen) | |
let output = String(cString: buffer) | |
print("response:", output) | |
} else { | |
print("empty response") | |
} | |
} | |
buffer.deallocate() | |
return result | |
} | |
func stream(_ stream: Stream, handle event: Stream.Event) { | |
print("Receieve stream event", event) | |
switch (event){ | |
case .errorOccurred: | |
print("ErrorOccurred") | |
break | |
case .endEncountered: | |
print("EndEncountered") | |
break | |
case .hasBytesAvailable: | |
print("HasBytesAvaible") | |
self.eventBlock?(event) | |
break | |
case .openCompleted: | |
print("OpenCompleted", stream) | |
self.eventBlock?(event) | |
break | |
case .hasSpaceAvailable: | |
print("HasSpaceAvailable", stream) | |
self.eventBlock?(event) | |
break | |
default: | |
print("default reached. unknown stream event") | |
break | |
} | |
} | |
} | |
func testAquos() { | |
let socket = Socket() | |
let host = "192.168.1.179" | |
let port = 10002 | |
var sent = false | |
_ = socket.connect(host, port) { event in | |
switch event { | |
case .openCompleted: | |
// print(socket.readAvailableBytes()) | |
break | |
case .hasSpaceAvailable: | |
if sent == false { | |
sent = true | |
print(socket.write(string: Aquos.setup.string)) | |
} | |
case .hasBytesAvailable: | |
print(socket.readAvailableBytes()) | |
default: | |
print("OK") | |
} | |
} | |
// socket.disconnect() | |
} | |
testAquos() | |
// run indefinitely | |
RunLoop.current.run(until: .distantFuture) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment