Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LegacyAir

Keep AirPods connected on iOS 6.

iOS 6 tears the A2DP stream down when nothing is playing, and modern AirPods then drop the link. On devices without a phone stack (iPod touch), they also fall into a ~40 second disconnect loop caused by a broken HFP battery report. LegacyAir fixes both.

What it does

Two independent modules in one package:

  1. Keep-alive (legacyair.dylib, injected into SpringBoard). While any Bluetooth device is connected, SpringBoard plays a continuous LPCM buffer through a mixable playback session, so the A2DP stream never closes.

    Two details are load-bearing:

    • The buffer is not digital silence. It carries a tone ~84 dB down, inaudible. A zeroed buffer makes mediaserverd report the audio as stopped 2.93 s in, even though the player is still running, and the stream then restarts every 11 s — worse than no keep-alive at all.
    • numberOfLoops does nothing on iOS 6. Continuity comes from starting a replacement player two seconds before the current one runs out.
  2. XAPL patch (legacyair-xapl.dylib, injected into BTServer). The pods send their battery level as AT+IPHONEACCEV=1,1,76 without the trailing CR. iOS 6 waits for that CR forever, the pods time out after ten seconds, reconnect, hit the same wall, and drop the ACL — a disconnect roughly every 40 seconds even mid-track.

    The module stops them from ever sending it, by clearing the feature bitmask in the host reply: +XAPL=iPhone,15 becomes +XAPL=iPhone,00. Nothing usable is lost on an iPod: there is nowhere to display a battery level.

    What it patches is a string constant, not code, so there is no hardcoded address. The module searches the daemon's __cstring section for +XAPL=iPhone, and rewrites the two digits after the comma. A daemon without that string is left untouched. It is armv7 only because no iOS 6 device is arm64.

The XAPL module is sandboxed away from /var/mobile, so it reports through syslog (legacyair xapl: ...) and is disabled by deleting the dylib:

rm /Library/MobileSubstrate/DynamicLibraries/legacyair-xapl.*
killall -9 BTServer

Install

Add the Cydia source, then search for LegacyAir:

http://dev-molly.space/repo

HTTP only: iOS 6 cannot validate modern Let's Encrypt certificates. If you previously installed Amy's ios-6-pods-hack, remove it first so the two do not both inject into SpringBoard:

dpkg -r ios-6-pods-hack

Without Cydia, copy legacyair.deb over, dpkg -i legacyair.deb, respring. If dpkg refuses the package, unpacking data.tar.gz into / and respringing is equivalent.

Building

./build.tool produces legacyair.deb with armv7 and arm64 slices. It runs on a current Xcode and needs nothing else — no old SDK, no Theos, no downloads. Current SDKs ship no armv7 slice and would bind the audio classes to AVFAudio.framework, which iOS 6 does not have, so the link goes against the hand-written stubs in stubs/. Add a stub entry whenever you import a new symbol, and keep it to symbols that iOS 6 exports.

Diagnostics

Create /var/mobile/.legacyair-alerts-enable and respring to get an alert for every state change plus a per-second trail in /var/mobile/legacyair.log showing each player's position. The flag is read once at load, so without it the logging costs nothing.

hcitrace.c is built into build/hcitrace.dylib but is not part of the package. It turns on BTServer's own HCI packet log (megabytes per minute). Copy it to the device by hand when a trace is needed, and delete it afterwards.

Testing

Please open an issue if the tweak does not work. Results so far:

works with this project

  • AirPods Pro 3 + iPod touch 4 + iOS 6.1.6 (keep-alive and XAPL module)

reported with the original keep-alive (Amy)

  • AirPods 2 + iPhone 4S + iOS 6.1.3
  • AirPods 2 + iPhone 5 + iOS 6.1.4 (meeza)
  • AirPods Pro 2 + iPhone 4S + iOS 6.1.3 (BodenLaman06)

works natively (assume all iOS 8+)

  • AirPods 2 + iPhone 4S + iOS 8.4.1
  • AirPods 2 + iPhone 4S + iOS 9.3.6

currently broken (investigating)

  • AirPods 2 + iPhone 5s + iOS 7.1.2 (meeza — loads but no improvement)
  • AirPods Pro + iPod touch 5 + iOS 6.1.3 (RossDarker — fixes pausing/skipping, still drops intermittently; the XAPL module was not part of those tests)

Credits

This is a substantial rework, published as its own project. The repositories used during development:

About

Keep AirPods connected on iOS 6. Jailbreak tweak (LegacyAir) for iPod touch, iPhone 4S and iPhone 5 - stops idle drop and the 40s disconnect loop. Cydia.

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Contributors

Languages