Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

This no longer works on tvOS 13 #180

Closed
jimz011 opened this issue Jun 25, 2019 · 54 comments
Closed

This no longer works on tvOS 13 #180

jimz011 opened this issue Jun 25, 2019 · 54 comments

Comments

@jimz011
Copy link

jimz011 commented Jun 25, 2019

I know it is early to mention this as tvOS 13 is still in beta, however I do want to point out that it does not work anymore with the current beta (beta 2) nor with the first beta. When scanning for devices it will just show up empty. I use Home Assistant mainly but I have tried it through the command line as well with no success. It does however seem to produce the authenticate screen (which will show the pin on screen). I can enter the pin, but nothing really happens. It will throw errors when trying to send commands manually.

I don't know if Apple changed anything to their software.

Just thought you might want a heads up.

@jimz011
Copy link
Author

jimz011 commented Jun 27, 2019

Ouch that sucks, I am guessing Apple will not have anything in its place. Too bad as tvOS13 is really great. Thanks for clarifying.

@slampus
Copy link

slampus commented Jul 3, 2019

Does it have with this known issue? Because then I feels like they are working with a fix for it.

https://developer.apple.com/documentation/tvos_release_notes/tvos_13_beta_3_release_notes

”AuthenticationServices
Known Issues
Passing both ASAuthorizationAppleIDProvider and ASAuthorizationPasswordProvider to ASAuthorizationController is not currently supported on tvOS. (50897359)”

@edwinolson
Copy link

I was able to fix this by modifying player.py, adding try: except: around the plist parsing.

           _LOGGER.debug('Playback-info (%d): %s', info.status, data)

            try:
                parsed = plistlib.loads(data)
            except:
                continue;

            # duration is only available if something is playing                                                 

Not being strong at all in python, I don't know if this is a good fix, but it "works for me". The first 'data' we get is empty (b''), but on the second read, 'data' gets real data.

@edwinolson
Copy link

Sorry, I should clarify: I had trouble with tvOS 13 as well, but I was only attempting to use "play_url". Authentication and pairing worked fine for me, but play_url would quit with an exception in plistlib.loads.

@timdreier
Copy link

@jimz011 how did you even make it to show the authentication screen? Just with atvremote pair? My AppleTV with iOS 13 won't show up with atvremote scan. Also with atvremote pair there won't come anything on screen at the AppleTV.

Would really love to make it work.

@CLARENNE-Q
Copy link

Not work with tvOS 13 Beta 4 :(

@Priva28
Copy link

Priva28 commented Jul 21, 2019

Not working for me either on the latest dev beta 4. Hopefully it is related to that issue the @slampus pointed out and they are actively working on it. Honestly, knowing Apple, it wouldn't surprise me if they patched this on purpose because it could be a "security issue".

@MorpheusAV
Copy link

It seems that port 3689 is no longer available or open on tvOS 13.

@jimz011
Copy link
Author

jimz011 commented Jul 24, 2019

@jimz011 how did you even make it to show the authentication screen? Just with atvremote pair? My AppleTV with iOS 13 won't show up with atvremote scan. Also with atvremote pair there won't come anything on screen at the AppleTV.

Would really love to make it work.

I did it through the command line, but there is nothing you can do with it, it will show you the screen on your ATV, you can enter a pin in HA, but that is basically it. Nothing gets paired. Actually nothing really happens at this point, no logs, just a bunch of nothing. Just what @MorpheusAV points out is that the port is no longer available. And as far as I know it will not be opened again due to the way Apple is phasing out Home Sharing in iOS 13 which is what this component needs to function. Itunes gets broken up in more applications which might have to do something with that.

So unfortunately I think there is no way to get this working again any time soon.

@Priva28
Copy link

Priva28 commented Jul 29, 2019

This still doesn’t work on the latest beta 5 release.

@postlund
Copy link
Owner

Sorry for not following up on this earlier, pyatv is quite low prio for me right now. Will probably get back to it later. Since Apple is dropping iTunes, it is very likely that the DAAP-support is removed at the same time. This would force the MediaRemote protocol to be used. This will effectively break Home Assistant support as the stable version of pyatv does not support it. Current master branch is experimental.

If someone could try to pair and and issue the playing command from master branch with --debug, that would help out troubleshooting.

@timdreier
Copy link

timdreier commented Jul 31, 2019

@postlund if you could tell me how to try I will do. But I didn’t made it through how to do the pairing.

@postlund
Copy link
Owner

atvremote --address <IP> --debug --protocol mrp pair

Should be enough for pairing. Try that first and let me know what happens.

@timdreier
Copy link

timdreier commented Jul 31, 2019

8.27 --debug --protocol mrp pair Traceback (most recent call last): File "/home/openhabian/.local/lib/python3.5/site-packages/pyatv-0.4.0.dev0-py3.5.egg/pyatv/__main__.py", line 490, in _run_application return await cli_handler(loop) File "/home/openhabian/.local/lib/python3.5/site-packages/pyatv-0.4.0.dev0-py3.5.egg/pyatv/__main__.py", line 315, in cli_handler return await _handle_commands(args, loop) File "/home/openhabian/.local/lib/python3.5/site-packages/pyatv-0.4.0.dev0-py3.5.egg/pyatv/__main__.py", line 405, in _handle_commands ret = await _handle_device_command(args, cmd, atv, loop) File "/home/openhabian/.local/lib/python3.5/site-packages/pyatv-0.4.0.dev0-py3.5.egg/pyatv/__main__.py", line 426, in _handle_device_command DeviceCommands(atv, loop, args), cmd, False, *cmd_args)) File "/home/openhabian/.local/lib/python3.5/site-packages/pyatv-0.4.0.dev0-py3.5.egg/pyatv/__main__.py", line 456, in _exec_command value = await tmp(*args) File "/home/openhabian/.local/lib/python3.5/site-packages/pyatv-0.4.0.dev0-py3.5.egg/pyatv/__main__.py", line 166, in pair await self.atv.pairing.start() File "/home/openhabian/.local/lib/python3.5/site-packages/pyatv-0.4.0.dev0-py3.5.egg/pyatv/mrp/__init__.py", line 322, in start await self.pairing_procedure.start_pairing() File "/home/openhabian/.local/lib/python3.5/site-packages/pyatv-0.4.0.dev0-py3.5.egg/pyatv/mrp/pairing.py", line 35, in start_pairing msg, generate_identifier=False) File "/home/openhabian/.local/lib/python3.5/site-packages/pyatv-0.4.0.dev0-py3.5.egg/pyatv/mrp/protocol.py", line 137, in send_and_receive await self._connect_and_encrypt() File "/home/openhabian/.local/lib/python3.5/site-packages/pyatv-0.4.0.dev0-py3.5.egg/pyatv/mrp/protocol.py", line 114, in _connect_and_encrypt await self.start() File "/home/openhabian/.local/lib/python3.5/site-packages/pyatv-0.4.0.dev0-py3.5.egg/pyatv/mrp/protocol.py", line 58, in start await self.connection.connect() File "/usr/lib/python3.5/asyncio/base_events.py", line 775, in create_connection raise exceptions[0] File "/usr/lib/python3.5/asyncio/base_events.py", line 762, in create_connection yield from self.sock_connect(sock, address) File "/usr/lib/python3.5/asyncio/selector_events.py", line 451, in sock_connect return (yield from fut) File "/usr/lib/python3.5/asyncio/futures.py", line 380, in __iter__ yield self # This tells Task to wait for completion. File "/usr/lib/python3.5/asyncio/tasks.py", line 304, in _wakeup future.result() File "/usr/lib/python3.5/asyncio/futures.py", line 293, in result raise self._exception File "/usr/lib/python3.5/asyncio/selector_events.py", line 481, in _sock_connect_cb raise OSError(err, 'Connect call failed %s' % (address,)) ConnectionRefusedError: [Errno 111] Connect call failed ('192.168.188.27', 0)

@postlund thats the result of it with the latest build!

@MorpheusAV
Copy link

MorpheusAV commented Jul 31, 2019

I get the same as above, however, if i append -a to the command I get some answers. Here is the results file for both commands.

https://pastebin.com/embed_js/FBR9fXBY

This is a similar result to issue the terminal command: dns-sd -Z _mediaremotetv._tcp

@postlund
Copy link
Owner

Oh, right. You must specify port manually as well. It changes between device reboots, so it's never the same. If you have something to browse for bonjour services with, you can find it that way (the service is called _mediaremotetv._tcp.local.).

Using auto discovery (flag -a) doesn't work with MRP unless you specify credentials manually, which is impossible during a pairing since it's during that process you obtain the credentials.

@MorpheusAV
Copy link

I used all the open ports in my case (49154) and pasted the result that returned a response here, looks like the same as with using -a option, is there anything that needs to be done?

https://pastebin.com/AcdNLcfj

Using Zenmap, the open ports on my ATV are:
5000 rtsp
7000 rtsp
7100 rtsp
49153 unknown
49154 unknown
49155 rtsp
62078 iphone-sync

@timdreier
Copy link

timdreier commented Jul 31, 2019

@postlund when I specify a port I get this (I replaced some numbers with x):

`8.27 --port 49152 --debug --protocol mrp pair
DEBUG: Connected to device
DEBUG: >> Send (Data=080f122465373635346664622d386466352d343262622d613463352d3032363734666235626339372000a2015e0a2462663262383232392d363333382d343265612d613362332d306637366565346462363134120570796174761a066950686f6e65220531344736302a12636f6d2e6170706c652e545652656d6f746532063237332e31323801403a7801)
DEBUG: >> Send: Protobuf=type: DEVICE_INFO_MESSAGE
identifier: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
priority: 0
[deviceInfoMessage] {
uniqueIdentifier: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
name: "pyatv"
localizedModelName: "iPhone"
systemBuildVersion: "14G60"
applicationBundleIdentifier: "com.apple.TVRemote"
applicationBundleVersion: "273.12"
protocolVersion: 1
lastSupportedMessageType: 58
supportsExtendedMotion: true
}

DEBUG: << Receive (Data=ea02080f122465373635346664622d386466352d343262622d613463352d3032363734666235626339372000a201bc020a2437323244443430332d314130392d343344302d383946382d333338453946383645344337120a576f686e7a696d6d65721a094170706c65c2a05456220831374a35353236652a16636f6d2e6170706c652e6d6564696172656d6f74656438014049480150016211636f6d2e6170706c652e54564d757369636801700178018801029a012442374634323244452d353641322d344246322d394342352d413535453545424437333430a2011139303a64643a35643a61393a64613a6162a80104b00101c00100d2012444364639323438422d453745382d343945302d383534412d313646323337323033313930e80101f00100fa0112636f6d2e6170706c652e706f64636173747382022444364639323438422d453745382d343945302d383534412d3136463233373230333139308a02095456416972506c6179)
DEBUG: << Receive: Protobuf=type: DEVICE_INFO_MESSAGE
identifier: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
priority: 0
[deviceInfoMessage] {
uniqueIdentifier: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
name: "Wohnzimmer"
localizedModelName: "Apple\302\240TV"
systemBuildVersion: "17J5526e"
applicationBundleIdentifier: "com.apple.mediaremoted"
protocolVersion: 1
lastSupportedMessageType: 73
supportsSystemPairing: true
allowsPairing: true
systemMediaApplication: "com.apple.TVMusic"
supportsACL: true
supportsSharedQueue: true
supportsExtendedMotion: true
sharedQueueVersion: 2
localReceiverPairingIdentity: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

DEBUG: >> Send (Data=08242000)
DEBUG: >> Send: Protobuf=type: SET_READY_STATE_MESSAGE
priority: 0

DEBUG: >> Send (Data=08102000aa01080801100118012001)
DEBUG: >> Send: Protobuf=type: CLIENT_UPDATES_CONFIG_MESSAGE
priority: 0
[clientUpdatesConfigMessage] {
artworkUpdates: true
nowPlayingUpdates: true
volumeUpdates: true
keyboardUpdates: true
}

DEBUG: >> Send (Data=08292000)
DEBUG: >> Send: Protobuf=type: WAKE_DEVICE_MESSAGE
priority: 0

DEBUG: << Receive (Data=0908282000e202020801)
DEBUG: << Receive: Protobuf=type: SET_HILITE_MODE_MESSAGE
priority: 0
[setHiliteModeMessage] {
hiliteMode: 1
}

DEBUG: >> Send (Data=08222000ba020a0a060601010001001000)
DEBUG: >> Send: Protobuf=type: CRYPTO_PAIRING_MESSAGE
priority: 0
[cryptoPairingMessage] {
pairingData: "\006\001\001\000\001\000"
status: 0
}

DEBUG: << Receive (Data=0f08222000ba02081019180020002800)
DEBUG: << Receive: Protobuf=type: CRYPTO_PAIRING_MESSAGE
priority: 0
[cryptoPairingMessage] {
status: 25
}

Traceback (most recent call last):
File "/home/openhabian/.local/lib/python3.5/site-packages/pyatv-0.4.0.dev0-py3.5.egg/pyatv/main.py", line 490, in _run_application
return await cli_handler(loop)
File "/home/openhabian/.local/lib/python3.5/site-packages/pyatv-0.4.0.dev0-py3.5.egg/pyatv/main.py", line 315, in cli_handler
return await _handle_commands(args, loop)
File "/home/openhabian/.local/lib/python3.5/site-packages/pyatv-0.4.0.dev0-py3.5.egg/pyatv/main.py", line 405, in _handle_commands
ret = await _handle_device_command(args, cmd, atv, loop)
File "/home/openhabian/.local/lib/python3.5/site-packages/pyatv-0.4.0.dev0-py3.5.egg/pyatv/main.py", line 426, in _handle_device_command
DeviceCommands(atv, loop, args), cmd, False, *cmd_args))
File "/home/openhabian/.local/lib/python3.5/site-packages/pyatv-0.4.0.dev0-py3.5.egg/pyatv/main.py", line 456, in _exec_command
value = await tmp(*args)
File "/home/openhabian/.local/lib/python3.5/site-packages/pyatv-0.4.0.dev0-py3.5.egg/pyatv/main.py", line 166, in pair
await self.atv.pairing.start()
File "/home/openhabian/.local/lib/python3.5/site-packages/pyatv-0.4.0.dev0-py3.5.egg/pyatv/mrp/init.py", line 322, in start
await self.pairing_procedure.start_pairing()
File "/home/openhabian/.local/lib/python3.5/site-packages/pyatv-0.4.0.dev0-py3.5.egg/pyatv/mrp/pairing.py", line 44, in start_pairing
self._atv_salt = pairing_data[tlv8.TLV_SALT]
KeyError: '2'

An error occurred, full stack trace above
DEBUG: Disconnected from device: None`

@postlund
Copy link
Owner

postlund commented Aug 1, 2019

I'm not entirely sure what happens here, but the device does not like the initial pairing message and returns an error code. Would probably have to sniff traffic from the real app and compare behavior, but I'm on vacation now so I won't be able to do that ATM.

@notabene00
Copy link

notabene00 commented Aug 4, 2019

resp here

resp = await self.protocol.send_and_receive(
is

DEBUG: << Receive: Protobuf=type: CRYPTO_PAIRING_MESSAGE
priority: 0
[cryptoPairingMessage] {
  status: -6735
}

atvremote --address 192.168.1.110 --protocol mrp pause --port 49156 (pause/play) are working as expected.

playing command is returning state:

Media type: Unknown
Play state: Paused
     Title: Сотня Сезон 6 Серия 12, Adjustment Protocol
    Artist: Элайза Тейлор, Мари Авгеропулос, Боб Морли, Генри Йен Кьюсик, Исайя Вашингтон, Пейдж Турко, Рики Уиттл, Ричард Хэрмон, Линдси Морган, Девон Бостик
  Position: 205/2539s (8.1%)

@jimz011
Copy link
Author

jimz011 commented Aug 12, 2019

Any progress on this? I would love to help but have not much knowledge about this stuff. If there is anything I can do to help (despite the noobfactor) tell me and I will do it.

@postlund
Copy link
Owner

I haven't had much time and I probably won't have for some time, but it seems strange that playing and pause seems to work.

@fantomnotabene Could you attach a complete debug log when doing for instance playing? Are you on the latest beta?

@notabene00
Copy link

tvOS 13.0 17J5549c to be precise.
play/pause/playing works via MRP found with autodiscovery.

/Users/fantom % atvremote --debug -a playing                                                                                                                                   10:26
DEBUG: Discovering devices for 3 seconds
DEBUG: Auto-discovered Гостиная at 192.168.1.110:49154 (protocol: 2)
DEBUG: Aborting since a device was found
INFO: Auto-discovered Гостиная at 192.168.1.110
DEBUG: Connected to device
DEBUG: >> Send (Data=080f122435656461386137392d663237372d346339332d613434612d6331643033316634626666612000a2015e0a2434656465393930662d363037612d343935302d383565322d366533383363323665643666120570796174761a066950686f6e65220531344736302a12636f6d2e6170706c652e545652656d6f746532063237332e31323801403a7801)
DEBUG: >> Send: Protobuf=type: DEVICE_INFO_MESSAGE
identifier: "5eda8a79-f277-4c93-a44a-c1d031f4bffa"
priority: 0
[deviceInfoMessage] {
  uniqueIdentifier: "4ede990f-607a-4950-85e2-6e383c26ed6f"
  name: "pyatv"
  localizedModelName: "iPhone"
  systemBuildVersion: "14G60"
  applicationBundleIdentifier: "com.apple.TVRemote"
  applicationBundleVersion: "273.12"
  protocolVersion: 1
  lastSupportedMessageType: 58
  supportsExtendedMotion: true
}

DEBUG: << Receive (Data=f002080f122435656461386137392d663237372d346339332d613434612d6331643033316634626666612000a201c2020a2437393043313637312d463742312d343336442d414438302d3833434643323230394634391210d093d0bed181d182d0b8d0bdd0b0d18f1a094170706c65c2a05456220831374a35353439632a16636f6d2e6170706c652e6d6564696172656d6f7465643801404b480150016211636f6d2e6170706c652e54564d757369636801700178018801029a012441433744314535382d323635312d344244382d383146432d304643354536344544303734a2011164633a35363a65373a33653a64313a6134a80104b00101c00101d2012438343931303643412d443543442d343937312d413939392d463745383332334637313337e80101f00100fa0112636f6d2e6170706c652e706f64636173747382022438343931303643412d443543442d343937312d413939392d4637453833323346373133378a02095456416972506c6179)
DEBUG: << Receive: Protobuf=type: DEVICE_INFO_MESSAGE
identifier: "5eda8a79-f277-4c93-a44a-c1d031f4bffa"
priority: 0
[deviceInfoMessage] {
  uniqueIdentifier: "790C1671-F7B1-436D-AD80-83CFC2209F49"
  name: "\320\223\320\276\321\201\321\202\320\270\320\275\320\260\321\217"
  localizedModelName: "Apple\302\240TV"
  systemBuildVersion: "17J5549c"
  applicationBundleIdentifier: "com.apple.mediaremoted"
  protocolVersion: 1
  lastSupportedMessageType: 75
  supportsSystemPairing: true
  allowsPairing: true
  systemMediaApplication: "com.apple.TVMusic"
  supportsACL: true
  supportsSharedQueue: true
  supportsExtendedMotion: true
  sharedQueueVersion: 2
  localReceiverPairingIdentity: "AC7D1E58-2651-4BD8-81FC-0FC5E64ED074"
}

DEBUG: >> Send (Data=08242000)
DEBUG: >> Send: Protobuf=type: SET_READY_STATE_MESSAGE
priority: 0

DEBUG: >> Send (Data=08102000aa01080801100118012001)
DEBUG: >> Send: Protobuf=type: CLIENT_UPDATES_CONFIG_MESSAGE
priority: 0
[clientUpdatesConfigMessage] {
  artworkUpdates: true
  nowPlayingUpdates: true
  volumeUpdates: true
  keyboardUpdates: true
}

DEBUG: >> Send (Data=08292000)
DEBUG: >> Send: Protobuf=type: WAKE_DEVICE_MESSAGE
priority: 0

DEBUG: << Receive (Data=0908162000da01020806)
DEBUG: << Receive: Protobuf=type: REGISTER_FOR_GAME_CONTROLLER_EVENTS_MESSAGE
priority: 0
[registerForGameControllerEventsMessage] {
}

DEBUG: << Receive (Data=eb01080420004ae4010a730a001221d094d0b0d0bdd0b8d0bbd0b020d09fd0bed0bfd0b5d180d0b5d187d0bdd18bd0b92d0000803f41e55e52c1f781c1414a3bd09fd09ed09fd095d0a0d095d0a7d09dd0abd09920d09cd09ed09920d09fd0a0d095d097d098d094d095d09dd0a2205bd0bfd0b8d0bbd0bed1825d880101123f0a04080510010a04080610000a04080210010a04080110000a07082d10008001000a0d081310002100000000000024400a0d081210002100000000000024402216636f6d2e676f6f676c652e696f732e796f75747562652a07596f755475626530014200591b2d13c1f781c141)
DEBUG: << Receive: Protobuf=type: SET_STATE_MESSAGE
priority: 0
[setStateMessage] {
  nowPlayingInfo {
    album: ""
    artist: "\320\224\320\260\320\275\320\270\320\273\320\260 \320\237\320\276\320\277\320\265\321\200\320\265\321\207\320\275\321\213\320\271"
    playbackRate: 1.0
    timestamp: 587460482.643521
    title: "\320\237\320\236\320\237\320\225\320\240\320\225\320\247\320\235\320\253\320\231 \320\234\320\236\320\231 \320\237\320\240\320\225\320\227\320\230\320\224\320\225\320\235\320\242 [\320\277\320\270\320\273\320\276\321\202]"
    isAlwaysLive: true
  }
  supportedCommands {
    supportedCommands {
      command: NextTrack
      enabled: true
    }
    supportedCommands {
      command: PreviousTrack
      enabled: false
    }
    supportedCommands {
      command: Pause
      enabled: true
    }
    supportedCommands {
      command: Play
      enabled: false
    }
    supportedCommands {
      command: SeekToPlaybackPosition
      enabled: false
      canScrub: 0
    }
    supportedCommands {
      command: SkipBackward
      enabled: false
      preferredIntervals: 10.0
    }
    supportedCommands {
      command: SkipForward
      enabled: false
      preferredIntervals: 10.0
    }
  }
  displayID: "com.google.ios.youtube"
  displayName: "YouTube"
  playbackState: 1
}

DEBUG: Dispatching message with type 4 (SetStateMessage) to Listener(func=<bound method MrpMetadata._handle_set_state of <pyatv.mrp.MrpMetadata object at 0x104de3438>>, data=None)
DEBUG: Dispatching message with type 4 (SetStateMessage) to Listener(func=<bound method MrpPushUpdater._handle_update of <pyatv.mrp.MrpPushUpdater object at 0x104de3400>>, data=None)
DEBUG: One-shot with message type 4 to Listener(func=<function MrpProtocol.start.<locals>._wait_for_updates at 0x104dd2d90>, data=<asyncio.locks.Semaphore object at 0x104de35f8 [locked, waiters:1]>)
Media type: Unknown
Play state: Playing
     Title: ПОПЕРЕЧНЫЙ МОЙ ПРЕЗИДЕНТ [пилот]
    Artist: Данила Поперечный
DEBUG: Disconnected from device: None

@boojew
Copy link

boojew commented Aug 22, 2019

Same issue as @timtim8461 I can provide more logs if needed

@jimz011
Copy link
Author

jimz011 commented Sep 12, 2019

Has anyone tried with the latest beta? And has anyone found a way to at least pair them and be able to read play/pause states?

@boojew
Copy link

boojew commented Sep 16, 2019

I tried w/ https://github.com/chamberlain2007/apple_tv_mrp/ and it that works. Havent tried pyatv

@postlund
Copy link
Owner

I'll see if I can help @chamberlain2007 in #181, maybe making this integration a bit more modern. I can do coaching, but not much coding.

If someone with the "KeyError: 2"-error could take a network dump (e.g. with tcpdump or Wireshark) and attach it here or send by email to me, I can verify if the pairing steps have changed.

@farstreet
Copy link

if you still need that and you can tell me what exactly to provide you, I can send it.

@jasoncodes
Copy link

I’ve ran into the same KeyError: '2' on self._atv_salt = pairing_data[tlv8.TLV_SALT] error after upgrading to tvOS 13.

Here is a packet capture of the current master commit (655dfcd) running python3 -m pyatv --address 192.168.14.219 --port 49154 --protocol mrp pair.

More than happy to help debug where I can.

@postlund
Copy link
Owner

I have a solution to this problem now, I will push a PR later.

@postlund
Copy link
Owner

Short follow-up. Started working on this but got caught up with bringing dependencies up-to-date as things have broken because of package updates. Also lots of warnings for deprecated functions. So I'm taking care of that now and I'm almost done. Will continue with fix after that.

@postlund
Copy link
Owner

Uplift done in #183, will continue with the rest soon.

@postlund
Copy link
Owner

Spamming a lot now, but if someone can test pairing with #184, that would be swell.

By accident I also figured out why scanning for devices works so flaky (lots of issues about that). So I will fix that soon as well!

@postlund
Copy link
Owner

Had to make some minor adjustments, but I have successfully paired and used the credentials with my Apple TV 4k running tvOS 13. So this should be solid, but would be nice with confirmation from someone else too.

@Mryck
Copy link

Mryck commented Sep 30, 2019

Hi on the tvos13_fix branch with an AppleTV 4K on tvOS 13, I can successfully pair with: atvremote -a pair and get the credentials. I can also successfully command the AppleTV with
atvremote -a --device_credentials (credentials) play or pause. Should I test other things ?

@farstreet
Copy link

farstreet commented Sep 30, 2019

I tried to install the current 'master' branch but when scanning for devices, it tells me that my Apple TV has no credentials. As far as I can see in the Settings on the Apple TV itself, under Users & Accounts, I seem to be logged on for iCloud, Game Center and Home Sharing. For completeness, I included below screenlogs of a version-check and the actual scan.

bash-5.0# pip show pyatv
Name: pyatv
Version: 0.4.0.dev0
Summary: Library for controlling an Apple TV
Home-page: https://github.com/postlund/pyatv
Author: Pierre Ståhl
Author-email: pierre.staahl@gmail.com
License: MIT
Location: /config/custom_components/pyatv
Requires: aiohttp, cryptography, curve25519-donna, ed25519, netifaces, protobuf, srptools, tlslite-ng, zeroconf
Required-by:

bash-5.0# atvremote scan
Device "Settings" at 10.10.10.36 supports these services:
 - Protocol: MRP, Port: 49152, Device Credentials: None
 - Protocol: AirPlay, Port: 7000

Note: You must use 'pair' with devices that have home sharing disabled

@MorpheusAV
Copy link

MorpheusAV commented Sep 30, 2019

I was able to pair consistently. Commands are also working.

Issuing the following commands sometimes discovers the ATV MRP and some times not.

$ atvremote -a --device_credentials fe9dbda08999d701673bf7c28411bf8e6604564c113ca0815ae242044706f638:17fc9d0497557d92169b9e2eec30d5aaffcdff10bde7c2bcb99ebbbf317ac84e:30306336643639312d613237392d343863362d386232392d643638313964316338613062:39353634613738362d373239372d346131342d616133632d326463383266356137356363 pause --debug
DEBUG: Discovering devices for 3 seconds
DEBUG: Auto-discovered Apple TV at 192.168.0.125:7000 (protocol: 3)
ERROR: Could not find any Apple TV on current network

$ atvremote -a --device_credentials fe9dbda08999d701673bf7c28411bf8e6604564c113ca0815ae242044706f638:17fc9d0497557d92169b9e2eec30d5aaffcdff10bde7c2bcb99ebbbf317ac84e:30306336643639312d613237392d343863362d386232392d643638313964316338613062:39353634613738362d373239372d346131342d616133632d326463383266356137356363 pause --debug
DEBUG: Discovering devices for 3 seconds
DEBUG: Auto-discovered Apple TV at 192.168.0.125:7000 (protocol: 3)
ERROR: Could not find any Apple TV on current network

$ atvremote -a --device_credentials fe9dbda08999d701673bf7c28411bf8e6604564c113ca0815ae242044706f638:17fc9d0497557d92169b9e2eec30d5aaffcdff10bde7c2bcb99ebbbf317ac84e:30306336643639312d613237392d343863362d386232392d643638313964316338613062:39353634613738362d373239372d346131342d616133632d326463383266356137356363 pause --debug
DEBUG: Discovering devices for 3 seconds
DEBUG: Auto-discovered Apple TV at 192.168.0.125:49152 (protocol: 2)
DEBUG: Aborting since a device was found
INFO: Auto-discovered Apple TV at 192.168.0.125
DEBUG: Connected to device
DEBUG: >> Send (Data=080f122462353032346163362d393631372d343535642d626564662d3537653838306665303231362000a2015e0a2439353634613738362d373239372d346131342d616133632d326463383266356137356363120570796174761a066950686f6e65220531344736302a12636f6d2e6170706c652e545652656d6f746532063237332e31323801403a7801)
DEBUG: >> Send: Protobuf=type: DEVICE_INFO_MESSAGE
identifier: "b5024ac6-9617-455d-bedf-57e880fe0216"
priority: 0
[deviceInfoMessage] {
uniqueIdentifier: "9564a786-7297-4a14-aa3c-2dc82f5a75cc"
name: "pyatv"
localizedModelName: "iPhone"
systemBuildVersion: "14G60"
applicationBundleIdentifier: "com.apple.TVRemote"
applicationBundleVersion: "273.12"
protocolVersion: 1
lastSupportedMessageType: 58
supportsExtendedMotion: true
}

DEBUG: << Receive (Data=e602080f122462353032346163362d393631372d343535642d626564662d3537653838306665303231362000a201b8020a2438333739363234382d343446382d343831392d423836392d39353441313542373032373512084170706c652054561a094170706c65c2a05456220631374a3538362a16636f6d2e6170706c652e6d6564696172656d6f7465643801404b480150016211636f6d2e6170706c652e54564d757369636801700178018801029a012434353933373830362d444443332d344144332d424230432d373541423741384634314637a2011134303a63623a63303a62623a32363a6534a80104b00101c00100d2012432304635463846462d463938322d344342312d394345312d423237414542353736394344e80101f00100fa0112636f6d2e6170706c652e706f64636173747382022432304635463846462d463938322d344342312d394345312d4232374145423537363943448a02095456416972506c6179)
DEBUG: << Receive: Protobuf=type: DEVICE_INFO_MESSAGE
identifier: "b5024ac6-9617-455d-bedf-57e880fe0216"
priority: 0
[deviceInfoMessage] {
uniqueIdentifier: "83796248-44F8-4819-B869-954A15B70275"
name: "Apple TV"
localizedModelName: "Apple\302\240TV"
systemBuildVersion: "17J586"
applicationBundleIdentifier: "com.apple.mediaremoted"
protocolVersion: 1
lastSupportedMessageType: 75
supportsSystemPairing: true
allowsPairing: true
systemMediaApplication: "com.apple.TVMusic"
supportsACL: true
supportsSharedQueue: true
supportsExtendedMotion: true
sharedQueueVersion: 2
localReceiverPairingIdentity: "45937806-DDC3-4AD3-BB0C-75AB7A8F41F7"
}

DEBUG: >> Send (Data=08222000ba022f0a250601010320bc06d41a5f945034f3f4ef9c15f8e8902b003375887e245b5cc1595bbf83064f1000180020002800)
DEBUG: >> Send: Protobuf=type: CRYPTO_PAIRING_MESSAGE
priority: 0
[cryptoPairingMessage] {
pairingData: "\006\001\001\003 \274\006\324\032_\224P4\363\364\357\234\025\370\350\220+\0003u\210~$[\\301Y[\277\203\006O"
status: 0
isRetrying: false
isUsingSystemPairing: false
state: 0
}

DEBUG: << Receive (Data=b20108222000ba02aa010a9f010578f7876c7bf61585dfab25016b864a384e9c184328ba914bdcfa7f3342b1d29932663de237d1bacaf984d2134be6eabce67bb553dd9417d618a660048aab8e69bcf4193a85ee3823ad9e2715d5c1813c2ea71c60664791f2a590d0ff04a8434258cf3c844f7c3f40ec3ce7b1d295f2c2cc18ba760475f33f340601020320ecef1b8dbc7eb321629ee85c3e9aaa62ed617ad55acc860cb2d7b68b285a11301000180020002800)
DEBUG: << Receive: Protobuf=type: CRYPTO_PAIRING_MESSAGE
priority: 0
[cryptoPairingMessage] {
pairingData: "\005x\367\207l{\366\025\205\337\253%\001k\206J8N\234\030C(\272\221K\334\372\1773B\261\322\2312f=\3427\321\272\312\371\204\322\023K\346\352\274\346{\265S\335\224\027\326\030\246\004\212\253\216i\274\364\031:\205\3568#\255\236\'\025\325\301\201<.\247\034fG\221\362\245\220\320\377\004\250CBX\317<\204O|?@\354<\347\261\322\225\362\302\314\030\272v\004u\363?4\006\001\002\003 \354\357\033\215\274~\263!b\236\350\>\232\252b\355az\325Z\314\206\014\262\327\266\213(Z\0210"
status: 0
isRetrying: false
isUsingSystemPairing: false
state: 0
}

DEBUG: Device (Encrypted=f7876c7bf61585dfab25016b864a384e9c184328ba914bdcfa7f3342b1d29932663de237d1bacaf984d2134be6eabce67bb553dd9417d618a660048aab8e69bcf4193a85ee3823ad9e2715d5c1813c2ea71c60664791f2a590d0ff04a8434258cf3c844f7c3f40ec3ce7b1d295f2c2cc18ba760475f33f34, Public=fe9dbda08999d701673bf7c28411bf8e6604564c113ca0815ae242044706f638)
DEBUG: >> Send (Data=08222000ba0287010a7d060103057869fd0c3d55b5191ba05151c0bc3e452b3253ea5f420578973c2de9b7831bac34c264ac18273bd4c2eab50f77f4bea43a2218f3a37d867badfb73544961a6b8cc0ca4d2d5aaa66d88a0a37b4488c57b3446557202f60386aba134279ac55f82da31277dc3e154bfc4be850fe68ebac308d0578beab9e07e981000180020002800)
DEBUG: >> Send: Protobuf=type: CRYPTO_PAIRING_MESSAGE
priority: 0
[cryptoPairingMessage] {
pairingData: "\006\001\003\005xi\375\014=U\265\031\033\240QQ\300\274>E+2S\352_B\005x\227<-\351\267\203\033\2544\302d\254\030';\324\302\352\265\017w\364\276\244:"\030\363\243}\206{\255\373sTIa\246\270\314\014\244\322\325\252\246m\210\240\243{D\210\305{4FUr\002\366\003\206\253\2414'\232\305_\202\3321'}\303\341T\277\304\276\205\017\346\216\272\303\010\320W\213\352\271\340~\230"
status: 0
isRetrying: false
isUsingSystemPairing: false
state: 0
}

DEBUG: << Receive (Data=1708222000ba02100a060701020601041000180020002800)
DEBUG: << Receive: Protobuf=type: CRYPTO_PAIRING_MESSAGE
priority: 0
[cryptoPairingMessage] {
pairingData: "\007\001\002\006\001\004"
status: 0
isRetrying: false
isUsingSystemPairing: false
state: 0
}

DEBUG: Keys (Input=1ef328d4f65b1a76a1131bc64a44e966e0576d27567e384e30df56369fec67ef, Output=d4bc3cba2b2d3bad777b7978931b0457c615f40cd4dedc8ab454afed69205d5d)
DEBUG: >> Send (Data=08242000)
DEBUG: >> Send (Encrypted=431367782bd9ed6ef7bc2e8d55d6d867ca85a61b)
DEBUG: >> Send: Protobuf=type: SET_READY_STATE_MESSAGE
priority: 0

DEBUG: >> Send (Data=08102000aa01080801100118012001)
DEBUG: >> Send (Encrypted=811732b2dedf3e45c8deaa50571c77454870f8fd68016cd6bd56dff3775497)
DEBUG: >> Send: Protobuf=type: CLIENT_UPDATES_CONFIG_MESSAGE
priority: 0
[clientUpdatesConfigMessage] {
artworkUpdates: true
nowPlayingUpdates: true
volumeUpdates: true
keyboardUpdates: true
}

DEBUG: >> Send (Data=08292000)
DEBUG: >> Send (Encrypted=438d7eef203396984e2096658f2df2e6aaadb99e)
DEBUG: >> Send: Protobuf=type: WAKE_DEVICE_MESSAGE
priority: 0

DEBUG: >> Send (Data=0801200032020802)
DEBUG: >> Send (Encrypted=0d20b34598ad36a5629f8917a7edea928ce95a9a24f81496)
DEBUG: >> Send: Protobuf=type: SEND_COMMAND_MESSAGE
priority: 0
[sendCommandMessage] {
command: Pause
}

DEBUG: Disconnected from device: None

@MorpheusAV
Copy link

If I send the command with the address and port, the response is much faster.

$atvremote --address 192.168.0.125 --device_credentials xxxxxx --port 49152 --protocol mrp play

However, the question is since the MRP changes the Port randomly, realistically I can't issue commands using the port number, so that leaves us having to do a discovery every time we need to send a command. This will cause lots of delays especially when scrolling through a movie list. Is there a solution for this? Or is discovery ( -a ) something that must be done before every command?

@postlund
Copy link
Owner

postlund commented Oct 1, 2019

@Mryck That is all I needed, thanks!

@farstreet master doesn't work yet, you need the changes from the mentioned PR (#184). I will merge that shortly.

@MorpheusAV Great, thanks for the additional report! Yes, the device change port at every boot (more or less) and the protocol mandates that you have to find the service via mDNS (zeroconf/bonjour). The scanning process is quite buggy and I have some improvements in the loop for that (as mentioned yesterday), but after some testing I found that they weren't as reliable as I had hoped. But at least better than now. So once I have those changes in place it should work better. But some additional delays is expected.

atvremote is more of a reference application and has its limitations. There are a few things builtin things that you can use. Either specify multiple commands at once, atvremote ... down down play pause, or use the the builtin in cli command, which lets you enter commands interactively (atvremote ... cli). Since this is mainly a library, you would have to write your own script to do more advanced things.

@MorpheusAV
Copy link

@MorpheusAV Great, thanks for the additional report! Yes, the device change port at every boot (more or less) and the protocol mandates that you have to find the service via mDNS (zeroconf/bonjour). The scanning process is quite buggy and I have some improvements in the loop for that (as mentioned yesterday), but after some testing I found that they weren't as reliable as I had hoped. But at least better than now. So once I have those changes in place it should work better. But some additional delays is expected.

The port number on the ATV (at least on my device here) changed randomly without a reboot. A reboot actually brings the ATV back to Port 49152 or 49153 on a regular basis. I believe that ports 49152-49156 are designated for MRP, however, my ATV has randomly changed to port 49667, 51221, among others. The other interesting thing is that when it changes to ports 49152-49156 it still responds to command as long as the command is directed to the right port. However when it goes above those ports it stops responding.

Another thing that has happened is that every time i sent a command, the ATV appended the port number by 1 (this is again once the port changes outside of the 52-56 range)

This happened when I performed lots of remote clicks. I wonder if the ATV thinks it's being attacked and changes the ports based on that.

@postlund
Copy link
Owner

postlund commented Oct 1, 2019

The port number on the ATV (at least on my device here) changed randomly without a reboot. A reboot actually brings the ATV back to Port 49152 or 49153 on a regular basis. I believe that ports 49152-49156 are designated for MRP, however, my ATV has randomly changed to port 49667, 51221, among others. The other interesting thing is that when it changes to ports 49152-49156 it still responds to command as long as the command is directed to the right port. However when it goes above those ports it stops responding.

The reason for this port selection is because a random port from the dynamic range is used. Instead of picking a specific port, the kernel will allocate "the next free" port. The recommended range for this is 49152-65535 according to IANA. XNU follows these recommendation, as can be seen here:

https://github.com/apple/darwin-xnu/blob/a449c6a3b8014d9406c2ddbdc81795da24aa7443/bsd/netinet/in.h#L288

You can get any port from that range, depending on port allocation algorithm. So this is expected behavior as far as I see it. It might keep old ports open for a while after changing for not breaking other clients or something, it would be more or less impossible to tell.

Another thing that has happened is that every time i sent a command, the ATV appended the port number by 1 (this is again once the port changes outside of the 52-56 range)

Hmm, I have not seen this before. Maybe it allocates a new port for each new client or something.

This happened when I performed lots of remote clicks. I wonder if the ATV thinks it's being attacked and changes the ports based on that.

Maybe pyatv is misbehaving in some way that makes the ATV do do some "recovery" mechanism and restart the MRP stack (this allocating a new port).

@postlund
Copy link
Owner

postlund commented Oct 1, 2019

I have created a new PR (#185) that hopefully improves scanning a bit. Wrote a script that scanned 200 times and verified that all my devices were found and it had 100% success rate. Doesn't mean that it will always work, but should at least be better than before. Would be awesome to get some input on this as well. Will merge to master when it's done since this fix is necessary no matter what.

@Kugelfang666
Copy link

sorry for my naive question, I'd like to give the updated version a spin but I don't know how. I'm currently running HA via Hass.io on my Raspberry pi. Can I simply copy the files from your repo over the corresponding files on the SD card?

@postlund
Copy link
Owner

postlund commented Oct 1, 2019

It's a valid question for sure. The API in pyatv 0.4.x is different in some places, making it hard to just do a drop-in replacement. We more or less need to rewrite the Home Assistant component to utilize new features to get things working again. I wrote a "few lines" about this in #181.

@postlund
Copy link
Owner

postlund commented Oct 3, 2019

Since this particular issue is fixed on master, I will close this issue now.

@postlund postlund closed this as completed Oct 3, 2019
@funtax
Copy link

funtax commented Oct 17, 2019

Hey @postlund , do you have an idea what we need to apply to https://github.com/funtax/AirPlayAuth to get it working again on tvOS13?
Currently it's sadly broken and I have like you not much time for investigation (congratulations to the second one @postlund ! Or is it the first child?).

Kind regards,
Martin

@postlund
Copy link
Owner

Could you elaborate on what is broken and provide some logs? The issue dealt with here (MRP) and AirPlay are two different things. So the fix here is not in any way applicable. Anyways, you could try if it works to authenticate with pyatv as it also has AirPlay support (based on the linked project). Just call with auth, e.g atvremote -a --debug auth.

Thank you! It's my second one - two boys now 😊

@philippe44
Copy link

philippe44 commented Oct 31, 2019

Hi - Sorry to bother you, but I have a bit the same question: is there something that needs to be changed when using AirPlay or is this something for MRP (which I don't know). I'm asking to see if I should update my AirPlay application (https://github.com/philippe44/LMS-to-Raop).

@postlund
Copy link
Owner

Hi - Sorry to bother you, but I have a bit the same question: is there something that needs to be changed when using AirPlay or is this something for MRP (which I don't know). I'm asking to see if I should update my AirPlay application (https://github.com/philippe44/LMS-to-Raop).

Same question as above, can you elaborate on what is actually broken? The change made here is for MRP only.

@funtax
Copy link

funtax commented Oct 31, 2019

@postlund @philippe44 Sorry for the delay, alot of work at the moment.
The issue has been solved with tvOS 13.2 which has been released a few days ago. I already checked it once it was in beta-state. So it seems to have been an issue with tvOS 13.0.

There's nothing to do on our side :)

@postlund
Copy link
Owner

@postlund @philippe44 Sorry for the delay, alot of work at the moment.
The issue has been solved with tvOS 13.2 which has been released a few days ago. I already checked it once it was in beta-state. So it seems to have been an issue with tvOS 13.0.

There's nothing to do on our side :)

Great, love it when no action is required! 👍

@domtik
Copy link

domtik commented Nov 5, 2019

Are you sure you sure that tvOS 13.2 solved the issue? I've just updated the AppleTV, restarted many times but the scan still not finding the device.

@postlund @philippe44 Sorry for the delay, alot of work at the moment.
The issue has been solved with tvOS 13.2 which has been released a few days ago. I already checked it once it was in beta-state. So it seems to have been an issue with tvOS 13.0.

There's nothing to do on our side :)

@postlund
Copy link
Owner

postlund commented Nov 5, 2019

Are you sure you sure that tvOS 13.2 solved the issue? I've just updated the AppleTV, restarted many times but the scan still not finding the device.

@postlund @philippe44 Sorry for the delay, alot of work at the moment.
The issue has been solved with tvOS 13.2 which has been released a few days ago. I already checked it once it was in beta-state. So it seems to have been an issue with tvOS 13.0.
There's nothing to do on our side :)

Can you provide some context on what you have tested with? Software-wise.

@funtax
Copy link

funtax commented Nov 5, 2019 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests