WifiDisplaySource.h revision cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34f
1/*
2 * Copyright 2012, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef WIFI_DISPLAY_SOURCE_H_
18
19#define WIFI_DISPLAY_SOURCE_H_
20
21#include "ANetworkSession.h"
22#include "VideoFormats.h"
23
24#include <media/stagefright/foundation/AHandler.h>
25
26#include <netinet/in.h>
27
28namespace android {
29
30struct IHDCP;
31struct IRemoteDisplayClient;
32struct ParsedMessage;
33struct TimeSyncer;
34
35// Represents the RTSP server acting as a wifi display source.
36// Manages incoming connections, sets up Playback sessions as necessary.
37struct WifiDisplaySource : public AHandler {
38    static const unsigned kWifiDisplayDefaultPort = 7236;
39
40    WifiDisplaySource(
41            const sp<ANetworkSession> &netSession,
42            const sp<IRemoteDisplayClient> &client,
43            const char *path = NULL);
44
45    status_t start(const char *iface);
46    status_t stop();
47
48    status_t pause();
49    status_t resume();
50
51protected:
52    virtual ~WifiDisplaySource();
53    virtual void onMessageReceived(const sp<AMessage> &msg);
54
55private:
56    struct PlaybackSession;
57    struct HDCPObserver;
58
59    enum State {
60        INITIALIZED,
61        AWAITING_CLIENT_CONNECTION,
62        AWAITING_CLIENT_SETUP,
63        AWAITING_CLIENT_PLAY,
64        ABOUT_TO_PLAY,
65        PLAYING,
66        PLAYING_TO_PAUSED,
67        PAUSED,
68        PAUSED_TO_PLAYING,
69        AWAITING_CLIENT_TEARDOWN,
70        STOPPING,
71        STOPPED,
72    };
73
74    enum {
75        kWhatStart,
76        kWhatRTSPNotify,
77        kWhatStop,
78        kWhatPause,
79        kWhatResume,
80        kWhatReapDeadClients,
81        kWhatPlaybackSessionNotify,
82        kWhatKeepAlive,
83        kWhatHDCPNotify,
84        kWhatFinishStop2,
85        kWhatTeardownTriggerTimedOut,
86        kWhatTimeSyncerNotify,
87    };
88
89    struct ResponseID {
90        int32_t mSessionID;
91        int32_t mCSeq;
92
93        bool operator<(const ResponseID &other) const {
94            return mSessionID < other.mSessionID
95                || (mSessionID == other.mSessionID
96                        && mCSeq < other.mCSeq);
97        }
98    };
99
100    typedef status_t (WifiDisplaySource::*HandleRTSPResponseFunc)(
101            int32_t sessionID, const sp<ParsedMessage> &msg);
102
103    static const int64_t kReaperIntervalUs = 1000000ll;
104
105    // We request that the dongle send us a "TEARDOWN" in order to
106    // perform an orderly shutdown. We're willing to wait up to 2 secs
107    // for this message to arrive, after that we'll force a disconnect
108    // instead.
109    static const int64_t kTeardownTriggerTimeouSecs = 2;
110
111    static const int64_t kPlaybackSessionTimeoutSecs = 30;
112
113    static const int64_t kPlaybackSessionTimeoutUs =
114        kPlaybackSessionTimeoutSecs * 1000000ll;
115
116    static const AString sUserAgent;
117
118    State mState;
119    VideoFormats mSupportedSourceVideoFormats;
120    sp<ANetworkSession> mNetSession;
121    sp<IRemoteDisplayClient> mClient;
122    AString mMediaPath;
123    sp<TimeSyncer> mTimeSyncer;
124    struct in_addr mInterfaceAddr;
125    int32_t mSessionID;
126
127    uint32_t mStopReplyID;
128
129    AString mWfdClientRtpPorts;
130    int32_t mChosenRTPPort;  // extracted from "wfd_client_rtp_ports"
131
132    bool mSinkSupportsVideo;
133    VideoFormats mSupportedSinkVideoFormats;
134
135    VideoFormats::ResolutionType mChosenVideoResolutionType;
136    size_t mChosenVideoResolutionIndex;
137
138    bool mSinkSupportsAudio;
139
140    bool mUsingPCMAudio;
141    int32_t mClientSessionID;
142
143    struct ClientInfo {
144        AString mRemoteIP;
145        AString mLocalIP;
146        int32_t mLocalPort;
147        int32_t mPlaybackSessionID;
148        sp<PlaybackSession> mPlaybackSession;
149    };
150    ClientInfo mClientInfo;
151
152    bool mReaperPending;
153
154    int32_t mNextCSeq;
155
156    KeyedVector<ResponseID, HandleRTSPResponseFunc> mResponseHandlers;
157
158    // HDCP specific section >>>>
159    bool mUsingHDCP;
160    bool mIsHDCP2_0;
161    int32_t mHDCPPort;
162    sp<IHDCP> mHDCP;
163    sp<HDCPObserver> mHDCPObserver;
164
165    bool mHDCPInitializationComplete;
166    bool mSetupTriggerDeferred;
167
168    bool mPlaybackSessionEstablished;
169
170    status_t makeHDCP();
171    // <<<< HDCP specific section
172
173    status_t sendM1(int32_t sessionID);
174    status_t sendM3(int32_t sessionID);
175    status_t sendM4(int32_t sessionID);
176
177    enum TriggerType {
178        TRIGGER_SETUP,
179        TRIGGER_TEARDOWN,
180        TRIGGER_PAUSE,
181        TRIGGER_PLAY,
182    };
183
184    // M5
185    status_t sendTrigger(int32_t sessionID, TriggerType triggerType);
186
187    status_t sendM16(int32_t sessionID);
188
189    status_t onReceiveM1Response(
190            int32_t sessionID, const sp<ParsedMessage> &msg);
191
192    status_t onReceiveM3Response(
193            int32_t sessionID, const sp<ParsedMessage> &msg);
194
195    status_t onReceiveM4Response(
196            int32_t sessionID, const sp<ParsedMessage> &msg);
197
198    status_t onReceiveM5Response(
199            int32_t sessionID, const sp<ParsedMessage> &msg);
200
201    status_t onReceiveM16Response(
202            int32_t sessionID, const sp<ParsedMessage> &msg);
203
204    void registerResponseHandler(
205            int32_t sessionID, int32_t cseq, HandleRTSPResponseFunc func);
206
207    status_t onReceiveClientData(const sp<AMessage> &msg);
208
209    status_t onOptionsRequest(
210            int32_t sessionID,
211            int32_t cseq,
212            const sp<ParsedMessage> &data);
213
214    status_t onSetupRequest(
215            int32_t sessionID,
216            int32_t cseq,
217            const sp<ParsedMessage> &data);
218
219    status_t onPlayRequest(
220            int32_t sessionID,
221            int32_t cseq,
222            const sp<ParsedMessage> &data);
223
224    status_t onPauseRequest(
225            int32_t sessionID,
226            int32_t cseq,
227            const sp<ParsedMessage> &data);
228
229    status_t onTeardownRequest(
230            int32_t sessionID,
231            int32_t cseq,
232            const sp<ParsedMessage> &data);
233
234    status_t onGetParameterRequest(
235            int32_t sessionID,
236            int32_t cseq,
237            const sp<ParsedMessage> &data);
238
239    status_t onSetParameterRequest(
240            int32_t sessionID,
241            int32_t cseq,
242            const sp<ParsedMessage> &data);
243
244    void sendErrorResponse(
245            int32_t sessionID,
246            const char *errorDetail,
247            int32_t cseq);
248
249    static void AppendCommonResponse(
250            AString *response, int32_t cseq, int32_t playbackSessionID = -1ll);
251
252    void scheduleReaper();
253    void scheduleKeepAlive(int32_t sessionID);
254
255    int32_t makeUniquePlaybackSessionID() const;
256
257    sp<PlaybackSession> findPlaybackSession(
258            const sp<ParsedMessage> &data, int32_t *playbackSessionID) const;
259
260    void finishStop();
261    void disconnectClientAsync();
262    void disconnectClient2();
263    void finishStopAfterDisconnectingClient();
264    void finishStop2();
265
266    void finishPlay();
267
268    DISALLOW_EVIL_CONSTRUCTORS(WifiDisplaySource);
269};
270
271}  // namespace android
272
273#endif  // WIFI_DISPLAY_SOURCE_H_
274