We use ExternalAccessory to talk to a smart card, i.e. a YubiKey 5Ci, over Lightning.
On iOS 27.0, most EASession objects we open are unable to receive.
NSStreamEventHasBytesAvailable never fires on the input stream and not one byte
arrives, yet the session reports no problem anywhere.
Environment
iPhone 11, iOS 27.0 build 24A437 (public release), YubiKey 5Ci on Lightning,
protocol com.yubico.ylp.
What we see on an affected session
both streams streamStatus 2 (NSStreamStatusOpen)
streamError on both nil
NSStreamEventOpenCompleted fires on both
hasSpaceAvailable before write YES
write:maxLength: returns 18 of 18
NSStreamEventHasSpaceAvailable fires
NSStreamEventErrorOccurred never
NSStreamEventEndEncountered never
NSStreamEventHasBytesAvailable never fires
inputStream.hasBytesAvailable false on every poll over 10 s
Everything reports success. Only the reply is missing.
Behaviour
A healthy session replies in single digit milliseconds. An affected one returns
nothing at all, ever. The condition is set when the session is created and never
changes. Opening another session on the same accessory is an independent roll of
the dice. Quitting and relaunching the app does not help. Only physically
detaching and reattaching the key does, after which connectionID increments and
the next session works.
15 of 25 sessions affected on 24A437. Also 9 of 20 on the 24A5430a beta, so it
predates the public release.
Already ruled out
Not a late reply, we waited 10 s. Not a missed event, we polled hasBytesAvailable
directly about 200 times per failure. Not a leaked session, teardown is
instrumented and every session deallocates exactly once. Not the hardware,
another app on the same phone and key reads its serial and firmware every time,
and that app opens one session and never closes it. The USB C interface of the
same key, via CryptoTokenKit, never fails.
Questions
Is there any supported way to tell at creation time that an EASession input
stream will not deliver data? Nothing we can read distinguishes the two cases.
Is repeatedly creating and releasing EASession objects for the same accessory
and protocol supported, and is any teardown step needed beyond clearing the
delegates, closing the streams, removing them from the run loop and releasing
the session?
Is there a supported way to recover without asking the user to unplug the
accessory?
1
0
28