-
Notifications
You must be signed in to change notification settings - Fork 57
/
Copy pathAirPlayCommon.h
executable file
·2575 lines (2024 loc) · 119 KB
/
AirPlayCommon.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
File: AirPlayCommon.h
Package: CarPlay Communications Plug-in.
Abstract: n/a
Version: 280.33.8
Disclaimer: IMPORTANT: This Apple software is supplied to you, by Apple Inc. ("Apple"), in your
capacity as a current, and in good standing, Licensee in the MFi Licensing Program. Use of this
Apple software is governed by and subject to the terms and conditions of your MFi License,
including, but not limited to, the restrictions specified in the provision entitled ”Public
Software”, and is further subject to your agreement to the following additional terms, and your
agreement that the use, installation, modification or redistribution of this Apple software
constitutes acceptance of these additional terms. If you do not agree with these additional terms,
please do not use, install, modify or redistribute this Apple software.
Subject to all of these terms and in consideration of your agreement to abide by them, Apple grants
you, for as long as you are a current and in good-standing MFi Licensee, a personal, non-exclusive
license, under Apple's copyrights in this original Apple software (the "Apple Software"), to use,
reproduce, and modify the Apple Software in source form, and to use, reproduce, modify, and
redistribute the Apple Software, with or without modifications, in binary form. While you may not
redistribute the Apple Software in source form, should you redistribute the Apple Software in binary
form, you must retain this notice and the following text and disclaimers in all such redistributions
of the Apple Software. Neither the name, trademarks, service marks, or logos of Apple Inc. may be
used to endorse or promote products derived from the Apple Software without specific prior written
permission from Apple. Except as expressly stated in this notice, no other rights or licenses,
express or implied, are granted by Apple herein, including but not limited to any patent rights that
may be infringed by your derivative works or by other works in which the Apple Software may be
incorporated.
Unless you explicitly state otherwise, if you provide any ideas, suggestions, recommendations, bug
fixes or enhancements to Apple in connection with this software (“Feedback”), you hereby grant to
Apple a non-exclusive, fully paid-up, perpetual, irrevocable, worldwide license to make, use,
reproduce, incorporate, modify, display, perform, sell, make or have made derivative works of,
distribute (directly or indirectly) and sublicense, such Feedback in connection with Apple products
and services. Providing this Feedback is voluntary, but if you do provide Feedback to Apple, you
acknowledge and agree that Apple may exercise the license granted above without the payment of
royalties or further consideration to Participant.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES, EXPRESS OR
IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR
IN COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION
AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Copyright (C) 2007-2015 Apple Inc. All Rights Reserved.
*/
#ifndef __AirPlayCommon_h__
#define __AirPlayCommon_h__
#include <CoreUtils/CommonServices.h>
#if 0
#pragma mark == Configuration ==
#endif
//===========================================================================================================================
// Configuration
//===========================================================================================================================
//#if( 1 && !defined( AIRPLAY_CONFIG_FILE_PATH ) )
// #define AIRPLAY_CONFIG_FILE_PATH "/etc/airplay.conf"
//#endif
#define AIRPLAY_CONFIG_FILE_PATH getenv("MH_CARPLAY_CONFIG_FILE_PATH")?getenv("MH_CARPLAY_CONFIG_FILE_PATH") : "/etc/carplay.ini"
// AIRPLAY_HTTP_SERVER_LEGACY: 1=Support legacy HTTP server port. 0=Only one, kAirPlayFixedPort_MediaControl(7000) port is supported.
#if( !defined( AIRPLAY_HTTP_SERVER_LEGACY ) )
#define AIRPLAY_HTTP_SERVER_LEGACY 0
#endif
// AIRPLAY_THREADED_MAIN: 1=Run AirPlay's "main" function in its own thread instead of exporting main (for non-process OS's).
#if( !defined( AIRPLAY_THREADED_MAIN ) )
#define AIRPLAY_THREADED_MAIN 0
#endif
// AIRTUNES_DYNAMIC_PORTS: 1=Bind to dynamic ports. 0=bind to fixed ports.
#if( !defined( AIRTUNES_DYNAMIC_PORTS ) )
#define AIRTUNES_DYNAMIC_PORTS 1
#endif
#if 0
#pragma mark -
#pragma mark == Constants ==
#endif
//===========================================================================================================================
// Constants
//===========================================================================================================================
#define kAirPlayConnectTimeoutSecs 10
#define kAirPlayConnectTimeoutNanos ( kAirPlayConnectTimeoutSecs * UINT64_C_safe( kNanosecondsPerSecond ) )
#define kAirPlayControlKeepAliveIntervalSecs 10
#define kAirPlayDataTimeoutSecs 30
#define kAirPlayStoppingDataTimeoutSecs 3
#define kAirPlayFixedPort_RTSPControl 5000 // TCP port for RTSP control.
#define kAirPlayFixedPort_RTSPEvents 5001 // TCP port for RTSP events.
#define kAirPlayFixedPort_DACP 5010 // TCP port for DACP events.
#define kAirPlayFixedPort_KeepAlive 5020 // UDP port for keep alive mechanism
#define kAirPlayFixedPort_RTPAudio 6000 // TCP or UDP port for RTP audio data.
#define kAirPlayFixedPort_RTCPLegacy 6001 // Old UDP port for RTCP packets (time announces, retransmits). Only for old devices.
#define kAirPlayFixedPort_TimeSyncLegacy 6002 // Old UDP port for time synchronization. Only for old devices.
#define kAirPlayFixedPort_RTPAltAudio 6003 // UDP port for receiving RTP alt audio data.
#define kAirPlayFixedPort_RTCPClient 6010 // UDP port for receiving retransmit requests.
#define kAirPlayFixedPort_RTCPServer 6011 // UDP port for receiving time announcements and retransmit responses.
#define kAirPlayFixedPort_TimeSyncClient 6020 // UDP port for receiving time sync responses.
#define kAirPlayFixedPort_TimeSyncServer 6021 // UDP port for receiving time sync requests.
#define kAirPlayFixedPort_RTPScreen 6030 // TCP port for receiving RTP screen data.
#define kAirPlayFixedPort_PerfDataClient 6100 // Base TCP or UDP port for receiving ACKs from a performance testing server.
#define kAirPlayFixedPort_PerfDataServer 6200 // Base TCP or UDP port for receiving data from a performance testing client.
#define kAirPlayFixedPort_MediaControl 7000 // TCP port for control and events for photos, slideshow, video, etc.
#define kAirPlayFixedPort_MediaData 7001 // TCP port for video file data.
#define kAirPlayFixedPort_ScreenNTPServer 7010 // UDP port for screen time synchronization requests.
#define kAirPlayFixedPort_ScreenNTPClient 7011 // UDP port for screen time synchronization responses.
#define kAirPlayFixedPort_ScreenData 7100 // TCP port for screen data (H.264 frames, meta data, etc.).
#if( AIRTUNES_DYNAMIC_PORTS )
#define kAirPlayPort_DACP 0
#define kAirPlayPort_KeepAlive 0
#define kAirPlayPort_MediaControl kAirPlayFixedPort_MediaControl
#define kAirPlayPort_MediaData kAirPlayFixedPort_MediaData
#define kAirPlayPort_RTCPClient 0
#define kAirPlayPort_RTCPServer 0
#define kAirPlayPort_RTPAudio 0
#define kAirPlayPort_RTPScreen 0
#define kAirPlayPort_RTPAltAudio 0
#define kAirPlayPort_RTSPControl kAirPlayFixedPort_RTSPControl
#define kAirPlayPort_RTSPEvents 0
#define kAirPlayPort_ScreenData kAirPlayFixedPort_ScreenData
#define kAirPlayPort_ScreenNTPClient kAirPlayFixedPort_ScreenNTPClient
#define kAirPlayPort_ScreenNTPServer kAirPlayFixedPort_ScreenNTPServer
#define kAirPlayPort_TimeSyncClient 0
#define kAirPlayPort_TimeSyncServer 0
#else
#define kAirPlayPort_DACP kAirPlayFixedPort_DACP
#define kAirPlayPort_KeepAlive kAirPlayFixedPort_KeepAlive
#define kAirPlayPort_MediaControl kAirPlayFixedPort_MediaControl
#define kAirPlayPort_MediaData kAirPlayFixedPort_MediaData
#define kAirPlayPort_RTCPClient kAirPlayFixedPort_RTCPClient
#define kAirPlayPort_RTCPServer kAirPlayFixedPort_RTCPServer
#define kAirPlayPort_RTPAudio kAirPlayFixedPort_RTPAudio
#define kAirPlayPort_RTPScreen kAirPlayFixedPort_RTPScreen
#define kAirPlayPort_RTPAltAudio kAirPlayFixedPort_RTPAltAudio
#define kAirPlayPort_RTSPControl kAirPlayFixedPort_RTSPControl
#define kAirPlayPort_RTSPEvents kAirPlayFixedPort_RTSPEvents
#define kAirPlayPort_ScreenData kAirPlayFixedPort_ScreenData
#define kAirPlayPort_ScreenNTPClient kAirPlayFixedPort_ScreenNTPClient
#define kAirPlayPort_ScreenNTPServer kAirPlayFixedPort_ScreenNTPServer
#define kAirPlayPort_TimeSyncClient kAirPlayFixedPort_TimeSyncClient
#define kAirPlayPort_TimeSyncServer kAirPlayFixedPort_TimeSyncServer
#endif
#define kAirTunesAESKeyLen 16
#define kAirPlayHTTPAuthenticationUsername "AirPlay"
#define kAirPlayHTTPAuthenticationRealm "AirPlay"
#define kAirPlayHTTPHeader_ClientName "X-Apple-Client-Name" // Name of the client device.
#define kAirPlayHTTPHeader_DeviceID "X-Apple-Device-ID" // Primary MAC address as a 64-bit hex value (e.g. 0x112233aabbcc).
#define kAirPlayHTTPHeader_Durations "X-Apple-Durations" // Semicolon-separated list of <name>=<milliseconds> durations.
#define kAirPlayHTTPHeader_HomeKitPairing "X-Apple-HKP" // Indicates if HomeKit pairing should be used.
#define kAirPlayHTTPHeader_EncryptionType "X-Apple-ET" // AirPlayEncryptionType to use.
#define kAirPlayHTTPHeader_PairDerive "X-Apple-PD" // Indicates if keys should be derived from pairing info.
#define kAirPlayHTTPHeader_ProtocolVersion "X-Apple-ProtocolVersion" // Version of the protocol.
#define kAirPlayHTTPHeader_AbsoluteTime "X-Apple-AbsoluteTime" // Current CFAbsoluteTime, seconds only
#define kAirTunesHTTPVersionStr "RTSP/1.0"
#define kAirPlayUUIDNameSpace ( (const uint8_t *) "\xBB\x40\x80\x51\xCC\x46\x40\x0B\x80\x68\xE9\x0D\xCB\xE8\xFB\x2B" )
// Audio
#define kAirPlayAudioBufferMainAltWiredMs 10 // 10 ms over wired.
#define kAirPlayAudioBufferMainAltWiFiMs 80 // 80 ms over WiFi.
#define kAirPlayAudioBufferMainHighMs 1000 // 1000 ms.
#define kAirPlayAudioLatencyOther 88200 // 2 seconds @ 44100 Hz.
#define kAirPlayAudioLatencyScreen 3750 // 85 ms @ 44100 Hz.
#define kAirPlayAudioLatencyThreshold 13230 // 300 ms @ 44100 Hz. Latency <= this uses redundant audio.
#define kAirPlayScreenLatencyWiredMs 25 // 25 ms over wired.
#define kAirPlayScreenLatencyWiFiMs 75 // 75 ms over WiFi.
#define kAirPlayAudioBitrateLowLatencyUpTo24KHz 48000 // 48 kbps.
#define kAirPlayAudioBitrateLowLatencyUpTo32KHz 64000 // 64 kbps.
#define kAirPlayAudioBitrateLowLatencyUpTo48KHz 96000 // 96 kbps.
#define kAirPlayAudioBitrateHighLatency 256000 // 256 kbps.
#define kAirPlaySamplesPerPacket_PCM 352 // Max samples per packet for PCM.
#define kAirTunesSampleRate 44100 // 44100 Hz.
#define AirTunesSamplesToMs( X ) ( ( ( 1000 * (X) ) + ( kAirTunesSampleRate / 2 ) ) / kAirTunesSampleRate )
#define AirTunesMsToSamples( X ) ( ( (X) * kAirTunesSampleRate ) / 1000 )
#define kAirTunesMaxSkewAdjustRate 441 // Max number of samples to insert/remove per second for skew compensation,
#define kAirTunesPlayoutDelay 11025 // 250 ms delay to sync with AirPort Express'es 250 ms buffer.
#define kAirTunesBitsPerSample 16 // 16-bit samples.
#define kAirTunesChannelCount 2 // Left + Right Channels
#define kAirTunesBytesPerUnit 4 // 2 bytes per channel and 2 channels per unit = 4 bytes.
#define kAirTunesInvalidVolumeDB -999
#define kAirTunesSilenceVolumeDB -144
#define kAirTunesMinVolumeDB -30
#define kAirTunesMaxVolumeDB 0
#define kAirTunesDisabledVolumeDB 1 // Special flag meaning "volume control is disabled" (line level).
#define kAirTunesMaxPacketSizeUDP 1472 // Enet MTU (1500) - IPv4 header (20) - UDP header (8) = 1472 (1460 RTP payload).
// Enet MTU (1500) - IPv6 header (40) - UDP header (8) = 1452 (1440 RTP payload).
// 12 byte RTP header + 1460 max payload (IPv4) or 1440 max payload (IPv6).
#define kAirTunesMaxPayloadSizeUDP 1440 // Enet MTU (1500) - IPv6 header (40) - UDP header (8) - RTP header (12) = 1440.
// Max Apple Lossless size is: samplesPerFrame * channelCount * ((10 + sampleSize) / 8) + 1. For example:
//
// AirTunes TCP: (4096 * 2 * ((10 + 16) / 8)) + 1 = 24577 and when rounded up to a power of 2 -> 32KB
// AirTunes UDP: ( 352 * 2 * ((10 + 16) / 8)) + 1 = 2113 and when rounded up to a power of 2 -> 4KB
#define AppleLosslessBufferSize( SAMPLES_PER_FRAME, CHANNEL_COUNT, BITS_PER_SAMPLE ) \
( ( (SAMPLES_PER_FRAME) * (CHANNEL_COUNT) * ( ( 10 + (BITS_PER_SAMPLE) ) / 8 ) ) + 1 )
#if( !defined( AirPlayIsBusyError ) )
#define AirPlayIsBusyError( X ) ( \
( (X) == HTTPStatusToOSStatus( kHTTPStatus_NotEnoughBandwidth ) ) || \
( (X) == kHTTPStatus_NotEnoughBandwidth ) || \
( (X) == kAlreadyInUseErr ) )
#endif
// AirPlayAudioJackStatus
#define kAirPlayAudioJackStatus_Disconnected "disconnected" // Nothing plugged in
#define kAirPlayAudioJackStatus_ConnectedAnalog "connected; type=analog" // Analog cable plugged in.
#define kAirPlayAudioJackStatus_ConnectedDigital "connected; type=digital" // Digital/optical cable plugged in.
#define kAirPlayAudioJackStatus_ConnectedUnknown "connected" // Unknown cable plugged in or can't detect cable.
// AirPlayCompressionType
typedef uint32_t AirPlayCompressionType;
#define kAirPlayCompressionType_Undefined 0
#define kAirPlayCompressionType_PCM ( 1 << 0 ) // 0x01: Uncompressed PCM.
#define kAirPlayCompressionType_ALAC ( 1 << 1 ) // 0x02: Apple Lossless (ALAC).
#define kAirPlayCompressionType_AAC_LC ( 1 << 2 ) // 0x04: AAC Low Complexity (AAC-LC).
#define kAirPlayCompressionType_AAC_ELD ( 1 << 3 ) // 0x08: AAC Enhanced Low Delay (AAC-ELD).
#define kAirPlayCompressionType_H264 ( 1 << 4 ) // 0x10: H.264 video.
#define kAirPlayCompressionType_OPUS ( 1 << 5 ) // 0x20: Opus.
#define AirPlayCompressionTypeToString( X ) ( \
( (X) == kAirPlayCompressionType_PCM ) ? "PCM" : \
( (X) == kAirPlayCompressionType_ALAC ) ? "ALAC" : \
( (X) == kAirPlayCompressionType_AAC_LC ) ? "AAC-LC" : \
( (X) == kAirPlayCompressionType_AAC_ELD ) ? "AAC-ELD" : \
( (X) == kAirPlayCompressionType_H264 ) ? "H.264" : \
( (X) == kAirPlayCompressionType_OPUS ) ? "Opus" : \
"?" )
// AirPlayDiscoveryMode
typedef uint32_t AirPlayDiscoveryMode;
#define kAirPlayDiscoveryMode_None 0 // No browse.
#define kAirPlayDiscoveryMode_Presence 1 // Browse until at least one instance of the given service is found.
#define kAirPlayDiscoveryMode_Detailed 2 // Full browse to find all instances of the given service.
// AirPlayDisplayFeatures
typedef uint32_t AirPlayDisplayFeatures;
#define kAirPlayDisplayFeatures_Knobs ( 1 << 1 ) // 0x02: Supports interacting via knobs.
#define kAirPlayDisplayFeatures_LowFidelityTouch ( 1 << 2 ) // 0x04: Supports interacting via low fidelity touch.
#define kAirPlayDisplayFeatures_HighFidelityTouch ( 1 << 3 ) // 0x08: Supports interacting via high fidelity touch.
#define kAirPlayDisplayFeatures_Touchpad ( 1 << 4 ) // 0x10: Supports interacting via touchpad.
typedef uint32_t AirPlayDisplayPrimaryInputDevice;
#define kAirPlayDisplayPrimaryInputDeviceUndeclared 0
#define kAirPlayDisplayPrimaryInputDeviceTouch 1
#define kAirPlayDisplayPrimaryInputDeviceTouchpad 2
#define kAirPlayDisplayPrimaryInputDeviceKnobs 3
// AirPlayEncryptionType
typedef uint32_t AirPlayEncryptionType;
#define kAirPlayEncryptionType_Undefined 0
#define kAirPlayEncryptionType_None ( 1 << 0 ) // 0x01: If set, encryption is not required.
#define kAirPlayEncryptionType_MFi_SAPv1 ( 1 << 4 ) // 0x10: If set, 128-bit AES key encrypted with MFi-SAPv1 is supported.
#define AirPlayEncryptionTypeToString( X ) \
( ( (X) == kAirPlayEncryptionType_None ) ? "None" : \
( (X) == kAirPlayEncryptionType_MFi_SAPv1 ) ? "MFi" : \
"?" )
// Prefixes used for deriving stream-specific keys and IVs:
//
// Key = Bytes 0-15 of SHA-512("AirPlayStreamKey" + <"read" | "write"> + <stream ID> + <session key>)
// IV = Bytes 0-15 of SHA-512("AirPlayStreamIV" + <"read" | "write"> + <stream ID> + <session key>)
#define kAirPlayEncryptionStreamPrefix_Key "AirPlayStreamKey"
#define kAirPlayEncryptionStreamPrefix_IV "AirPlayStreamIV"
#define kAirPlayTLS_PSK_Salt "Pair-TLS-PSK"
// AirPlaySessionType
typedef uint32_t AirPlaySessionType;
#define kAirPlaySessionType_Screen 0
#define kAirPlaySessionType_Audio 1
// AirPlayStreamType
typedef uint32_t AirPlayStreamType;
#define kAirPlayStreamType_Invalid 0 // Reserved for an invalid type.
#define kAirPlayStreamType_GeneralAudio 96 // RTP payload type for general audio output (2 second latency). UDP.
#define kAirPlayStreamType_MainAudio 100 // RTP payload type for low-latency audio input/output. UDP.
#define kAirPlayStreamType_AltAudio 101 // RTP payload type for low-latency UI sounds, alerts, etc. output. UDP.
#define kAirPlayStreamType_MainHighAudio 102 // RTP payload type for high-latency audio output. UDP.
#define kAirPlayStreamType_Screen 110 // RTP payload type for H.264 screen output. TCP.
#define kAirPlayStreamType_Playback 120 // AirPlay Video commands
#define AirPlayStreamTypeToString( X ) \
( ( (X) == kAirPlayStreamType_GeneralAudio ) ? "GeneralAudio" : \
( (X) == kAirPlayStreamType_MainAudio ) ? "MainAudio" : \
( (X) == kAirPlayStreamType_MainHighAudio ) ? "MainHighAudio" : \
( (X) == kAirPlayStreamType_AltAudio ) ? "AltAudio" : \
( (X) == kAirPlayStreamType_Screen ) ? "Screen" : \
"?" )
#define AirPlayStreamTypeToCFString( X ) \
( ( (X) == kAirPlayStreamType_GeneralAudio ) ? CFSTR( "GeneralAudio" ) : \
( (X) == kAirPlayStreamType_MainAudio ) ? CFSTR( "MainAudio" ) : \
( (X) == kAirPlayStreamType_MainHighAudio ) ? CFSTR( "MainHighAudio" ) : \
( (X) == kAirPlayStreamType_AltAudio ) ? CFSTR( "AltAudio" ) : \
( (X) == kAirPlayStreamType_Screen ) ? CFSTR( "Screen" ) : \
CFSTR( "?" ) )
// AirPlayStatusFlags
typedef uint32_t AirPlayStatusFlags;
#define kAirPlayStatusFlag_None 0
#define kAirPlayStatusFlag_ProblemsExist ( 1 << 0 ) // 0x0001: Problem has been detected.
#define kAirPlayStatusFlag_Unconfigured ( 1 << 1 ) // 0x0002: Device is not configured.
#define kAirPlayStatusFlag_AudioLink ( 1 << 2 ) // 0x0004: Audio cable is attached.
#define kAirPlayStatusFlag_PairPIN ( 1 << 9 ) // 0x0200: PIN required to pair.
// WiFi Statistics Reporting
#define kAirPlayWifiStatUpdateIntervalSeconds 3
// Constants for deriving session encryption keys.
#define kAirPlayPairingControlKeySaltPtr "Control-Salt"
#define kAirPlayPairingControlKeySaltLen sizeof_string( kAirPlayPairingControlKeySaltPtr )
#define kAirPlayPairingControlKeyReadInfoPtr "Control-Read-Encryption-Key"
#define kAirPlayPairingControlKeyReadInfoLen sizeof_string( kAirPlayPairingControlKeyReadInfoPtr )
#define kAirPlayPairingControlKeyWriteInfoPtr "Control-Write-Encryption-Key"
#define kAirPlayPairingControlKeyWriteInfoLen sizeof_string( kAirPlayPairingControlKeyWriteInfoPtr )
#define kAirPlayPairingEventsKeySaltPtr "Events-Salt"
#define kAirPlayPairingEventsKeySaltLen sizeof_string( kAirPlayPairingEventsKeySaltPtr )
#define kAirPlayPairingEventsKeyReadInfoPtr "Events-Read-Encryption-Key"
#define kAirPlayPairingEventsKeyReadInfoLen sizeof_string( kAirPlayPairingEventsKeyReadInfoPtr )
#define kAirPlayPairingEventsKeyWriteInfoPtr "Events-Write-Encryption-Key"
#define kAirPlayPairingEventsKeyWriteInfoLen sizeof_string( kAirPlayPairingEventsKeyWriteInfoPtr )
#define kAirPlayPairingDataStreamKeySaltPtr "DataStream-Salt"
#define kAirPlayPairingDataStreamKeySaltLen sizeof_string( kAirPlayPairingDataStreamKeySaltPtr )
#define kAirPlayPairingDataStreamKeyInputInfoPtr "DataStream-Input-Encryption-Key"
#define kAirPlayPairingDataStreamKeyInputInfoLen sizeof_string( kAirPlayPairingDataStreamKeyInputInfoPtr )
#define kAirPlayPairingDataStreamKeyOutputInfoPtr "DataStream-Output-Encryption-Key"
#define kAirPlayPairingDataStreamKeyOutputInfoLen sizeof_string( kAirPlayPairingDataStreamKeyOutputInfoPtr )
// Constants for vehicle information
/*---------------------------------------------------------------------------------------------------------------------------
ETC: Indicates that an electronic toll collection device is installed in the vehicle (an ETC icon will be shown). [CFDictionary]
Keys
------------
kAirPlayKey_Active -- Whether or not ETC is currently active in the vehicle (determines whether gray or color icon is shown).
*/
#define kAirPlayVehicleInformation_ETC "ElectronicTollCollection"
#if 0
#pragma mark -
#pragma mark == Audio Formats ==
#endif
//===========================================================================================================================
// Audio Formats
//===========================================================================================================================
typedef uint64_t AirPlayAudioFormat;
#define kAirPlayAudioFormat_Invalid 0
#define kAirPlayAudioFormat_Reserved1 ( 1 << 0 ) // 0x00000001
#define kAirPlayAudioFormat_Reserved2 ( 1 << 1 ) // 0x00000002
#define kAirPlayAudioFormat_PCM_8KHz_16Bit_Mono ( 1 << 2 ) // 0x00000004
#define kAirPlayAudioFormat_PCM_8KHz_16Bit_Stereo ( 1 << 3 ) // 0x00000008
#define kAirPlayAudioFormat_PCM_16KHz_16Bit_Mono ( 1 << 4 ) // 0x00000010
#define kAirPlayAudioFormat_PCM_16KHz_16Bit_Stereo ( 1 << 5 ) // 0x00000020
#define kAirPlayAudioFormat_PCM_24KHz_16Bit_Mono ( 1 << 6 ) // 0x00000040
#define kAirPlayAudioFormat_PCM_24KHz_16Bit_Stereo ( 1 << 7 ) // 0x00000080
#define kAirPlayAudioFormat_PCM_32KHz_16Bit_Mono ( 1 << 8 ) // 0x00000100
#define kAirPlayAudioFormat_PCM_32KHz_16Bit_Stereo ( 1 << 9 ) // 0x00000200
#define kAirPlayAudioFormat_PCM_44KHz_16Bit_Mono ( 1 << 10 ) // 0x00000400
#define kAirPlayAudioFormat_PCM_44KHz_16Bit_Stereo ( 1 << 11 ) // 0x00000800
#define kAirPlayAudioFormat_PCM_44KHz_24Bit_Mono ( 1 << 12 ) // 0x00001000
#define kAirPlayAudioFormat_PCM_44KHz_24Bit_Stereo ( 1 << 13 ) // 0x00002000
#define kAirPlayAudioFormat_PCM_48KHz_16Bit_Mono ( 1 << 14 ) // 0x00004000
#define kAirPlayAudioFormat_PCM_48KHz_16Bit_Stereo ( 1 << 15 ) // 0x00008000
#define kAirPlayAudioFormat_PCM_48KHz_24Bit_Mono ( 1 << 16 ) // 0x00010000
#define kAirPlayAudioFormat_PCM_48KHz_24Bit_Stereo ( 1 << 17 ) // 0x00020000
#define kAirPlayAudioFormat_ALAC_44KHz_16Bit_Stereo ( 1 << 18 ) // 0x00040000
#define kAirPlayAudioFormat_ALAC_44KHz_24Bit_Stereo ( 1 << 19 ) // 0x00080000
#define kAirPlayAudioFormat_ALAC_48KHz_16Bit_Stereo ( 1 << 20 ) // 0x00100000
#define kAirPlayAudioFormat_ALAC_48KHz_24Bit_Stereo ( 1 << 21 ) // 0x00200000
#define kAirPlayAudioFormat_AAC_LC_44KHz_Stereo ( 1 << 22 ) // 0x00400000
#define kAirPlayAudioFormat_AAC_LC_48KHz_Stereo ( 1 << 23 ) // 0x00800000
#define kAirPlayAudioFormat_AAC_ELD_44KHz_Stereo ( 1 << 24 ) // 0x01000000
#define kAirPlayAudioFormat_AAC_ELD_48KHz_Stereo ( 1 << 25 ) // 0x02000000
#define kAirPlayAudioFormat_AAC_ELD_16KHz_Mono ( 1 << 26 ) // 0x04000000
#define kAirPlayAudioFormat_AAC_ELD_24KHz_Mono ( 1 << 27 ) // 0x08000000
#define kAirPlayAudioFormat_OPUS_16KHz_Mono ( 1 << 28 ) // 0x10000000
#define kAirPlayAudioFormat_OPUS_24KHz_Mono ( 1 << 29 ) // 0x20000000
#define kAirPlayAudioFormat_OPUS_48KHz_Mono ( 1 << 30 ) // 0x40000000
#define kAirPlayAudioFormatMask_PCM ( kAirPlayAudioFormat_PCM_8KHz_16Bit_Mono | \
kAirPlayAudioFormat_PCM_8KHz_16Bit_Stereo | \
kAirPlayAudioFormat_PCM_16KHz_16Bit_Mono | \
kAirPlayAudioFormat_PCM_16KHz_16Bit_Stereo | \
kAirPlayAudioFormat_PCM_24KHz_16Bit_Mono | \
kAirPlayAudioFormat_PCM_24KHz_16Bit_Stereo | \
kAirPlayAudioFormat_PCM_32KHz_16Bit_Mono | \
kAirPlayAudioFormat_PCM_32KHz_16Bit_Stereo | \
kAirPlayAudioFormat_PCM_44KHz_16Bit_Mono | \
kAirPlayAudioFormat_PCM_44KHz_16Bit_Stereo | \
kAirPlayAudioFormat_PCM_44KHz_24Bit_Mono | \
kAirPlayAudioFormat_PCM_44KHz_24Bit_Stereo | \
kAirPlayAudioFormat_PCM_48KHz_16Bit_Mono | \
kAirPlayAudioFormat_PCM_48KHz_16Bit_Stereo | \
kAirPlayAudioFormat_PCM_48KHz_24Bit_Mono | \
kAirPlayAudioFormat_PCM_48KHz_24Bit_Stereo )
#define kAirPlayAudioFormatMask_ALAC ( kAirPlayAudioFormat_ALAC_44KHz_16Bit_Stereo | \
kAirPlayAudioFormat_ALAC_44KHz_24Bit_Stereo | \
kAirPlayAudioFormat_ALAC_48KHz_16Bit_Stereo | \
kAirPlayAudioFormat_ALAC_48KHz_24Bit_Stereo )
#define kAirPlayAudioFormatMask_AAC_LC ( kAirPlayAudioFormat_AAC_LC_44KHz_Stereo | \
kAirPlayAudioFormat_AAC_LC_48KHz_Stereo )
#define kAirPlayAudioFormatMask_AAC_ELD ( kAirPlayAudioFormat_AAC_ELD_44KHz_Stereo | \
kAirPlayAudioFormat_AAC_ELD_48KHz_Stereo | \
kAirPlayAudioFormat_AAC_ELD_16KHz_Mono | \
kAirPlayAudioFormat_AAC_ELD_24KHz_Mono )
#define kAirPlayAudioFormatMask_OPUS ( kAirPlayAudioFormat_OPUS_16KHz_Mono | \
kAirPlayAudioFormat_OPUS_24KHz_Mono | \
kAirPlayAudioFormat_OPUS_48KHz_Mono )
#define AirPlayAudioFormatToString( X ) ( \
( (X) == kAirPlayAudioFormat_Invalid ) ? "Invalid" : \
( (X) == kAirPlayAudioFormat_PCM_8KHz_16Bit_Mono ) ? "PCM/8000/16/1" : \
( (X) == kAirPlayAudioFormat_PCM_8KHz_16Bit_Stereo ) ? "PCM/8000/16/2" : \
( (X) == kAirPlayAudioFormat_PCM_16KHz_16Bit_Mono ) ? "PCM/16000/16/1" : \
( (X) == kAirPlayAudioFormat_PCM_16KHz_16Bit_Stereo ) ? "PCM/16000/16/2" : \
( (X) == kAirPlayAudioFormat_PCM_24KHz_16Bit_Mono ) ? "PCM/24000/16/1" : \
( (X) == kAirPlayAudioFormat_PCM_24KHz_16Bit_Stereo ) ? "PCM/24000/16/2" : \
( (X) == kAirPlayAudioFormat_PCM_32KHz_16Bit_Mono ) ? "PCM/32000/16/1" : \
( (X) == kAirPlayAudioFormat_PCM_32KHz_16Bit_Stereo ) ? "PCM/32000/16/2" : \
( (X) == kAirPlayAudioFormat_PCM_44KHz_16Bit_Mono ) ? "PCM/44100/16/1" : \
( (X) == kAirPlayAudioFormat_PCM_44KHz_16Bit_Stereo ) ? "PCM/44100/16/2" : \
( (X) == kAirPlayAudioFormat_PCM_44KHz_24Bit_Mono ) ? "PCM/44100/24/1" : \
( (X) == kAirPlayAudioFormat_PCM_44KHz_24Bit_Stereo ) ? "PCM/44100/24/2" : \
( (X) == kAirPlayAudioFormat_PCM_48KHz_16Bit_Mono ) ? "PCM/48000/16/1" : \
( (X) == kAirPlayAudioFormat_PCM_48KHz_16Bit_Stereo ) ? "PCM/48000/16/2" : \
( (X) == kAirPlayAudioFormat_PCM_48KHz_24Bit_Mono ) ? "PCM/48000/24/1" : \
( (X) == kAirPlayAudioFormat_PCM_48KHz_24Bit_Stereo ) ? "PCM/48000/24/2" : \
( (X) == kAirPlayAudioFormat_ALAC_44KHz_16Bit_Stereo ) ? "ALAC/44100/16/2" : \
( (X) == kAirPlayAudioFormat_ALAC_44KHz_24Bit_Stereo ) ? "ALAC/44100/24/2" : \
( (X) == kAirPlayAudioFormat_ALAC_48KHz_16Bit_Stereo ) ? "ALAC/48000/16/2" : \
( (X) == kAirPlayAudioFormat_ALAC_48KHz_24Bit_Stereo ) ? "ALAC/48000/24/2" : \
( (X) == kAirPlayAudioFormat_AAC_LC_44KHz_Stereo ) ? "AAC-LC/44100/2" : \
( (X) == kAirPlayAudioFormat_AAC_LC_48KHz_Stereo ) ? "AAC-LC/48000/2" : \
( (X) == kAirPlayAudioFormat_AAC_ELD_44KHz_Stereo ) ? "AAC-ELD/44100/2" : \
( (X) == kAirPlayAudioFormat_AAC_ELD_48KHz_Stereo ) ? "AAC-ELD/48000/2" : \
( (X) == kAirPlayAudioFormat_AAC_ELD_16KHz_Mono ) ? "AAC-ELD/16000/1" : \
( (X) == kAirPlayAudioFormat_AAC_ELD_24KHz_Mono ) ? "AAC-ELD/24000/1" : \
( (X) == kAirPlayAudioFormat_OPUS_16KHz_Mono ) ? "OPUS/16000/1" : \
( (X) == kAirPlayAudioFormat_OPUS_24KHz_Mono ) ? "OPUS/24000/1" : \
( (X) == kAirPlayAudioFormat_OPUS_48KHz_Mono ) ? "OPUS/48000/1" : \
"Unknown" )
#if 0
#pragma mark -
#pragma mark == Bonjour ==
#endif
//===========================================================================================================================
// Bonjour
//===========================================================================================================================
// _airplay._tcp
#define kAirPlayBonjourServiceType "_airplay._tcp."
#define kAirPlayBonjourServiceDomain "local."
#define kAirPlayTXTKey_DeviceID "deviceid" // [String] Globally unique ID of the device. MUST be persistent across reboots.
#define kAirPlayTXTKey_Features "features" // [Number][AirPlayFeatures] Supported features.
#define kAirPlayTXTKey_Flags "flags" // [Hex integer][AirPlayStatusFlags] System flags.
#define kAirPlayTXTKey_FirmwareVersion "fv" // [String] Firmware Source Version (e.g. 1.2.3).
#define kAirPlayTXTKey_Model "model" // [String] Model of device (e.g. Device1,1). MUST be globally unique.
#define kAirPlayTXTKey_PublicHKID "pi" // [String] HomeKit identifier string - usually MAC address, but not necessarily
#define kAirPlayTXTKey_PublicKey "pk" // [Hex string] 32-byte Ed25519 public key.
#define kAirPlayTXTKey_ProtocolVersion "protovers" // [String] Protocol version string (e.g. "1.0"). Missing means 1.0.
#define kAirPlayTXTKey_Seed "seed" // [Integer] Config seed number. Increment on any software config change.
#define kAirPlayTXTKey_SourceVersion "srcvers" // [String] Source version string (e.g. "101.7").
#if 0
#pragma mark -
#pragma mark == Commands ==
#endif
//===========================================================================================================================
// Commands
//===========================================================================================================================
// HTTP resource path for sending commands from an AirPlay client to an AirPlay server.
// Request payload: Optional binary plist. See kAirPlayCommand_* for command-specific details.
// Response payload: Optional binary plist.
#define kAirPlayCommandPath "/command"
/*---------------------------------------------------------------------------------------------------------------------------
ActivationChanged: Tells the server that the device's activation state has changed.
No request keys.
No response keys.
*/
#define kAirPlayCommand_ActivationChanged "activationChanged"
/*---------------------------------------------------------------------------------------------------------------------------
ConfigChanged: Tells the server that the system's configuration has changed (e.g. network configuration changed).
No request keys.
No response keys.
*/
#define kAirPlayCommand_ConfigChanged "configChanged"
/*---------------------------------------------------------------------------------------------------------------------------
UpdateAdvertising: Command to update advertising on the AirPlay receiver.
No request keys.
No response keys.
*/
#define kAirPlayCommand_UpdateAdvertising "updateAdvertising"
/*---------------------------------------------------------------------------------------------------------------------------
SetConfig: Sets the configuration to use for the accessory (e.g. WiFi SSID, name, password, etc.).
The configuration should be validated and saved off, but not applied until the subsequent ApplyConfig command.
Applying the configuration before ApplyConfig could cause a loss of connectivity and prevent the controller from
receiving the response. This would appear to the controller as a failure to set the configuration. Waiting for the
ApplyConfig command (which is not sent over the network, but handled internally) ensures a reliable configuration.
Request keys
------------
kAirPlayKey_AdminPassword -- Optional password to be required to administer the accessory.
kAirPlayKey_Name -- Optional name to give the accessory.
kAirPlayKey_PlayPassword -- Optional password to be required to play to the accessory.
kAirPlayKey_WiFiPSK -- PSK for joining a WPA-protected network.
kAirPlayKey_WiFiSSID -- SSID the accessory should join.
Response keys
-------------
kAirPlayKey_Params -- Optional parameters returned by the accessory (e.g. Apple App Store info).
kAirPlayKey_Status -- Result of setting the configuration.
*/
#define kAirPlayCommand_SetConfig "setConfig"
/*---------------------------------------------------------------------------------------------------------------------------
ApplyConfig: Applies the configuration previously set with the SetConfig command.
Note: this command is never sent over the network. It's only used internally for reliable configuration.
No request keys.
No response keys.
*/
#define kAirPlayCommand_ApplyConfig "applyConfig"
/*---------------------------------------------------------------------------------------------------------------------------
DuckAudio: Ramps volume down (e.g. Fade down music to play a voice prompt).
Request keys
------------
[kAirPlayKey_Decibels] -- Relative decibel reduction after duck (e.g. -3 means 3 dB less than pre-Duck volume).
[kAirPlayKey_DurationMs] -- Number of milliseconds the ramp down should last.
No response keys.
*/
#define kAirPlayCommand_DuckAudio "duckAudio"
/*---------------------------------------------------------------------------------------------------------------------------
UnduckAudio: Ramps volume back to the pre-duck level (e.g. restore music volume after an audible alert).
Request keys
------------
kAirPlayKey_DurationMs -- Number of milliseconds the ramp up should last.
No response keys.
*/
#define kAirPlayCommand_UnduckAudio "unduckAudio"
/*---------------------------------------------------------------------------------------------------------------------------
FlushAudio: Flush any unplayed audio data. Used when pause is pressed, when the user seeks to a different spot, etc.
No request keys.
No response keys.
*/
#define kAirPlayCommand_FlushAudio "flushAudio"
/*---------------------------------------------------------------------------------------------------------------------------
DisableBluetooth: Disable Bluetooth connectivity to specified device.
Request keys
------------
kAirPlayKey_DeviceID -- MAC address of Bluetooth device to disable connectivity to.
No response keys.
*/
#define kAirPlayCommand_DisableBluetooth "disableBluetooth"
/*---------------------------------------------------------------------------------------------------------------------------
UpdateFeedback: Provides any input feedback from the controller and returns any output feedback to the controller.
No request keys
Response keys
-------------
kAirPlayKey_Streams -- Array of streams with feedback.
kAirPlayKey_Type -- Type of stream.
kAirPlayKey_SampleRate -- Estimated sample rate
*/
#define kAirPlayCommand_UpdateFeedback "updateFeedback"
/*---------------------------------------------------------------------------------------------------------------------------
HIDSendReport: Sends a HID input report from accessory to controller.
Request keys
------------
kAirPlayKey_HIDReport -- Report to send.
kAirPlayKey_UUID -- UUID of the HID device to send the report from.
No response keys.
*/
#define kAirPlayCommand_HIDSendReport "hidSendReport"
/*---------------------------------------------------------------------------------------------------------------------------
HIDSetReport: Sets HID report on a HID device. The HID device is specified by UUID.
Request keys
------------
kAirPlayKey_HIDReport -- Report to set.
kAirPlayKey_UUID -- UUID of the HID device to set the report on.
No response keys.
*/
#define kAirPlayCommand_SetHIDReport "hidSetReport"
/*---------------------------------------------------------------------------------------------------------------------------
HIDCopyInputMode: Copies HID input mode from a HID device. The HID device is specified by UUID.
Request keys
------------
kAirPlayKey_UUID -- UUID of the HID device to set the report on.
Response keys
-------------
kAirPlayKey_HIDInputMode -- Input mode.
*/
#define kAirPlayCommand_HIDCopyInputMode "hidCopyInputMode"
/*---------------------------------------------------------------------------------------------------------------------------
HIDSetInputMode: Sets HID input mode on a HID device. The HID device is specified by UUID.
Request keys
------------
kAirPlayKey_HIDInputMode -- Input mode to set.
kAirPlayKey_UUID -- UUID of the HID device to set the input mode on.
No response keys.
*/
#define kAirPlayCommand_HIDSetInputMode "hidSetInputMode"
/*---------------------------------------------------------------------------------------------------------------------------
iAPSendMessage: Sends an iAP message to the receiver.
Request keys
------------
kAirPlayKey_Data -- iAP message data to send.
No response keys.
*/
#define kAirPlayCommand_iAPSendMessage "iAPSendMessage"
/*---------------------------------------------------------------------------------------------------------------------------
ForceKeyFrame: Tells the server to request a key frame from the sender. Used when the decoder crashes, etc.
No request keys.
No response keys.
*/
#define kAirPlayCommand_ForceKeyFrame "forceKeyFrame"
/*---------------------------------------------------------------------------------------------------------------------------
GetLogs: Generate an archive of currently available logs on the receiver and provide a path to the generated archive.
No request keys.
Response keys
-------------
kAirPlayKey_Path -- Path to the generated log archive
*/
#define kAirPlayCommand_GetLogs "getLogs"
/*---------------------------------------------------------------------------------------------------------------------------
ChangeModes: For the accessory to requests mode changes (e.g. take main audio).
Request keys
------------
kAirPlayKey_AppStates -- App states to change. Each dictionary entry contains the following keys:
kAirPlayKey_AppStateID -- ID of app state to change.
[kAirPlayKey_State] -- For non-speech app states, this is whether the app state is true/false.
[kAirPlayKey_SpeechMode] -- For speech, this is the speech mode to change to.
kAirPlayKey_Resources -- Resources to change. Each dictionary entry contains the following keys:
kAirPlayKey_ResourceID -- ID of resource to change.
kAirPlayKey_TransferType -- Type of change to make (e.g. take, borrow, etc.).
[kAirPlayKey_TransferPriority] -- If "take" or "borrow", priority of request (e.g. nice-to-have, etc.).
[kAirPlayKey_TakeConstraint] -- If "take", constraint for peer to take. Missing otherwise.
[kAirPlayKey_BorrowConstraint] -- If "take", constraint for peer to borrow. Missing otherwise.
[kAirPlayKey_UnborrowConstraint] -- If "borrow", constraint for peer to unborrow. Missing otherwise.
Response keys
-------------
kAirPlayKey_Params -- Latest modes property. See the ModesChanged command for keys, etc.
kAirPlayKey_Status -- Result of perform the mode change. If this is non-zero, the change failed.
*/
#define kAirPlayCommand_ChangeModes "changeModes"
/*---------------------------------------------------------------------------------------------------------------------------
ModesChanged: For the controller to indicate to the accessory that modes have changed (e.g. now on a phone call).
Request keys
------------
kAirPlayKey_AppStates -- Changed app states. Each dictionary entry contains the following keys:
kAirPlayKey_AppStateID -- App state that changed.
kAirPlayKey_Entity -- Entity that now owns the app state.
[kAirPlayKey_SpeechMode] -- For speech, this the new speech mode.
kAirPlayKey_Resources -- Changed resources. Each dictionary entry contains the following keys:
kAirPlayKey_ResourceID -- Resource that changed.
kAirPlayKey_Entity -- Entity that now owns the resource.
kAirPlayKey_ReasonStr -- Optional human readable reason the change occurred.
No response keys.
*/
#define kAirPlayCommand_ModesChanged "modesChanged"
/*---------------------------------------------------------------------------------------------------------------------------
PrefsChanged: Tells the server that the prefs have changed and it should re-read them.
No request keys.
No response keys.
*/
#define kAirPlayEvent_PrefsChanged "prefsChanged"
/*---------------------------------------------------------------------------------------------------------------------------
UpdatePrefs: Hook for the platform to update any platform-specific prefs it might have.
No request keys.
No response keys.
*/
#define kAirPlayCommand_UpdatePrefs "updatePrefs"
/*---------------------------------------------------------------------------------------------------------------------------
RequestSiri: Requests that Siri be invoked with a specified action.
Request keys
------------
kAirPlayKey_SiriAction -- Siri action to invoke (e.g. prewarm, buttowndown, etc.).
No response keys.
*/
#define kAirPlayCommand_RequestSiri "requestSiri"
/*---------------------------------------------------------------------------------------------------------------------------
RequestUI: Requests UI to be shown on the other side (e.g. for accessory to ask the controller to show the maps app).
Request keys
------------
kAirPlayKey_URL -- Optional URL of the app to launch.
No response keys.
*/
#define kAirPlayCommand_RequestUI "requestUI"
/*---------------------------------------------------------------------------------------------------------------------------
SetNightMode: Indicates whether or not apps should alter their display for night mode.
Request keys
------------
kAirPlayKey_NightMode -- Boolean indicting whether or not to enable night mode.
No response keys.
*/
#define kAirPlayCommand_SetNightMode "setNightMode"
/*---------------------------------------------------------------------------------------------------------------------------
SetLimitedUI: Indicates whether or not apps should enable UI limitations.
Request keys
------------
kAirPlayKey_LimitedUI -- Boolean indicating whether or not display certain UI elements should be limited.
No response keys.
*/
#define kAirPlayCommand_SetLimitedUI "setLimitedUI"
/*---------------------------------------------------------------------------------------------------------------------------
StartServer
For the server object, this starts listening for pref changes and may start or stop based on the prefs.
For the platform object, this tells it that server is enabled and gives the platform to perform any active setup.
No request keys.
No response keys.
*/
#define kAirPlayCommand_StartServer "startServer"
/*---------------------------------------------------------------------------------------------------------------------------
StopServer
For the server object, this stops all activity on the server (including the listening for pref changes).
For the platform object, this tells it that server has fully stopped.
No request keys.
No response keys.
*/
#define kAirPlayCommand_StopServer "stopServer"
/*---------------------------------------------------------------------------------------------------------------------------
SessionDied: Tells the server that a session has died (i.e. communication is no longer working).
Qualifier is the AirPlayReceiverSessionRef that died.
No request keys.
No response keys.
*/
#define kAirPlayCommand_SessionDied "sessionDied"
/*---------------------------------------------------------------------------------------------------------------------------
StartSession: Tells the platform that a session has started so it can do any active setup.
No request keys.
No response keys.
*/
#define kAirPlayCommand_StartSession "startSession"
/*---------------------------------------------------------------------------------------------------------------------------
StopSession: Tells the platform that a session has stopped so it should stop any active session-specific operations.
No request keys.
No response keys.
*/
#define kAirPlayCommand_StopSession "stopSession"
/*---------------------------------------------------------------------------------------------------------------------------
UpdateVehicleInformation: For the controller to indicate to the accessory that vehicle information has changed.
Request keys
------------
kAirPlayKey_VehicleInformation -- New vehicle information.
No response keys.
*/
#define kAirPlayCommand_UpdateVehicleInformation "updateVehicleInformation"
/*---------------------------------------------------------------------------------------------------------------------------
StartedPlayingOverP2PSolo: Tells the server that a P2P Solo playback session started.
No response keys.
*/
#define kAirPlayEvent_StartedPlayingOverP2PSolo "startedPlayingOverP2PSolo"
/*---------------------------------------------------------------------------------------------------------------------------
StoppedPlayingOverP2PSolo: Tells the server that a P2P Solo playback session stopped.
No response keys.
*/
#define kAirPlayEvent_StoppedPlayingOverP2PSolo "stoppedPlayingOverP2PSolo"
/*---------------------------------------------------------------------------------------------------------------------------
SetUpStreams: Sets up one or more streams on the platform. May be call multiple times to set up different streams.
Request keys
------------
kAirPlayKey_Streams -- Array of stream descriptions for the streams to set up and their parameters.
Response keys
-------------
kAirPlayKey_Streams -- Array of stream descriptions providing info about each set up stream.
*/
#define kAirPlayCommand_SetUpStreams "setUpStreams"
/*---------------------------------------------------------------------------------------------------------------------------
TearDownStreams: Tears down one or more streams on the platform. May be call multiple times to tear down different streams.
Note: This may tear down streams at different times and in a different order than they were set up. For example, it
may set up main audio, screen, and HID streams then a minute later tear down only main audio then a minute after that
it may tear down main audio and HID. So this shouldn't make any assumptions about how streams were set up.
Request keys
------------
kAirPlayKey_Streams -- Array of stream descriptions for the streams to tear down.
No response keys.
*/
#define kAirPlayCommand_TearDownStreams "tearDownStreams"
/*---------------------------------------------------------------------------------------------------------------------------
UpdateTimestamps: Debug hook for receiving a dictionary containing timestamp info.
Request keys
------------
"frameCount" -- Total number of frames processed so far. Also acts as the frame number.
"metrics" -- Array of timestamp deltas in milliseconds. See kAirPlayProperty_TimestampInfo for labels.
No response keys.
*/
#define kAirPlayCommand_UpdateTimestamps "updateTimestamps"
#if 0
#pragma mark -
#pragma mark == Features ==
#endif
//===========================================================================================================================
// Features
//===========================================================================================================================
typedef uint64_t AirPlayFeatures;
#define kAirPlayFeature_Screen ( 1 << 7 ) // 0x0000000080: Screen mirroring.
#define kAirPlayFeature_Rotate ( 1 << 8 ) // 0x0000000100: Can rotate during screen mirroring.
#define kAirPlayFeature_Audio ( 1 << 9 ) // 0x0000000200: Audio.
#define kAirPlayFeature_RedundantAudio ( 1 << 11 ) // 0x0000000800: Redundant audio packets to handle loss.
#define kAirPlayFeature_AudioPCM ( 1 << 18 ) // 0x0000040000: Uncompressed PCM audio data.
#define kAirPlayFeature_AudioAAC_LC ( 1 << 20 ) // 0x0000100000: AAC-LC audio compression.
#define kAirPlayFeature_AudioUnencrypted ( 1 << 22 ) // 0x0000400000: Unencrypted audio.
#define kAirPlayFeature_AudioAES_128_MFi_SAPv1 ( 1 << 26 ) // 0x0004000000: Audio: 128-bit AES key encrypted with MFi-SAPv1.
#define kAirPlayFeature_Pairing ( 1 << 27 ) // 0x0008000000: Pairing support.
#define kAirPlayFeature_UnifiedBonjour ( 1 << 30 ) // 0x0040000000: _airplay._tcp and _raop._tcp are unified (_raop._tcp for compatibility only).
#define kAirPlayFeature_Reserved ( 1 << 31 ) // 0x0080000000: Reserved to avoid client bugs treating this as a sign bit.
#define kAirPlayFeature_Car ( UINT64_C( 1 ) << 32 ) // 0x0100000000: Car support.
#define kAirPlayFeature_CarPlayControl ( UINT64_C( 1 ) << 37 ) // 0x2000000000: Supports CarPlayControl protocol for initiating connections.
#define kAirPlayFeature_HKPairingAndEncrypt ( UINT64_C( 1 ) << 38 ) // 0x4000000000: Control channel encryption.
#if 0
#pragma mark -
#pragma mark == Extended Features ==
#endif
//===========================================================================================================================
// Extended Features
//===========================================================================================================================
// Specifies that the accessory supports receiving information about the telephony voice coder during stream setup
#define kAirPlayExtendedFeature_VocoderInfo "vocoderInfo"
// Specifies that the accessory supports enhanced Car UI requests (such as AC_BACK handling)
#define kAirPlayExtendedFeature_EnhancedRequestCarUI "enhancedRequestCarUI"
#if 0
#pragma mark -
#pragma mark == Keys ==
#endif
//===========================================================================================================================
// Keys
//===========================================================================================================================
// [Boolean] Whether or not something is active.
#define kAirPlayKey_Active "active"
// [String] IP address, DNS name, etc.
#define kAirPlayKey_Address "address"
// [String] Password used to change settings on the accessory (e.g. configure the network, etc.).
#define kAirPlayKey_AdminPassword "adminPassword"
// [Number:AirPlayAppStateID] ID of an app state (e.g. phone call). See kAirPlayAppStateID_*.
#define kAirPlayKey_AppStateID "appStateID"
// [Array] Array of app states for mode changes, etc.
#define kAirPlayKey_AppStates "appStates"