feat(ios): USB TCP frame server
Add USBServer: an NWListener on a fixed local TCP port that usbmuxd tunnels to the tethered Mac. Sends AVLiveWire frames and exposes a connection-state callback.
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
import Foundation
|
||||
import Network
|
||||
import AVLiveWire
|
||||
|
||||
/// TCP listener on a fixed local port. usbmuxd tunnels it to the
|
||||
/// tethered Mac — the port is never advertised on any network.
|
||||
final class USBServer {
|
||||
static let port: UInt16 = 7000
|
||||
|
||||
enum State { case idle, listening, connected }
|
||||
var onState: ((State) -> Void)?
|
||||
|
||||
private var listener: NWListener?
|
||||
private var connection: NWConnection?
|
||||
private let queue = DispatchQueue(label: "cc.avlive.usbserver")
|
||||
|
||||
func start() {
|
||||
let params = NWParameters.tcp
|
||||
params.allowLocalEndpointReuse = true
|
||||
listener = try? NWListener(using: params,
|
||||
on: NWEndpoint.Port(rawValue: Self.port)!)
|
||||
listener?.newConnectionHandler = { [weak self] conn in
|
||||
self?.adopt(conn)
|
||||
}
|
||||
listener?.start(queue: queue)
|
||||
onState?(.listening)
|
||||
}
|
||||
|
||||
private func adopt(_ conn: NWConnection) {
|
||||
connection?.cancel()
|
||||
connection = conn
|
||||
conn.stateUpdateHandler = { [weak self] st in
|
||||
switch st {
|
||||
case .ready: self?.onState?(.connected)
|
||||
case .failed, .cancelled: self?.onState?(.listening)
|
||||
default: break
|
||||
}
|
||||
}
|
||||
conn.start(queue: queue)
|
||||
}
|
||||
|
||||
/// Send one framed message. Drops silently if no peer.
|
||||
func send(tag: FrameTag, pid: Int16, timestamp: Double,
|
||||
payload: Data) {
|
||||
guard let conn = connection else { return }
|
||||
let header = FrameHeader(tag: tag, pid: pid,
|
||||
timestamp: timestamp, length: UInt32(payload.count))
|
||||
conn.send(content: header.encoded() + payload,
|
||||
completion: .contentProcessed { _ in })
|
||||
}
|
||||
|
||||
func stop() {
|
||||
connection?.cancel(); listener?.cancel()
|
||||
onState?(.idle)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user