WifiDisplaySource.h revision e7bd24af08ef0722fb124a550662bcec48c56f86
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
23#include <media/stagefright/foundation/AHandler.h>
24
25#include <netinet/in.h>
26
27namespace android {
28
29#define REQUIRE_HDCP            1
30
31struct IHDCP;
32struct IRemoteDisplayClient;
33struct ParsedMessage;
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
44    status_t start(const char *iface);
45    status_t stop();
46
47protected:
48    virtual ~WifiDisplaySource();
49    virtual void onMessageReceived(const sp<AMessage> &msg);
50
51private:
52    struct PlaybackSession;
53
54#if REQUIRE_HDCP
55    struct HDCPObserver;
56#endif
57
58    enum State {
59        INITIALIZED,
60        AWAITING_CLIENT_CONNECTION,
61        AWAITING_CLIENT_SETUP,
62        AWAITING_CLIENT_PLAY,
63        ABOUT_TO_PLAY,
64        PLAYING,
65        AWAITING_CLIENT_TEARDOWN,
66        STOPPING,
67        STOPPED,
68    };
69
70    enum {
71        kWhatStart,
72        kWhatRTSPNotify,
73        kWhatStop,
74        kWhatReapDeadClients,
75        kWhatPlaybackSessionNotify,
76        kWhatKeepAlive,
77        kWhatHDCPNotify,
78        kWhatFinishStop2,
79        kWhatTeardownTriggerTimedOut,
80    };
81
82    struct ResponseID {
83        int32_t mSessionID;
84        int32_t mCSeq;
85
86        bool operator<(const ResponseID &other) const {
87            return mSessionID < other.mSessionID
88                || (mSessionID == other.mSessionID
89                        && mCSeq < other.mCSeq);
90        }
91    };
92
93    typedef status_t (WifiDisplaySource::*HandleRTSPResponseFunc)(
94            int32_t sessionID, const sp<ParsedMessage> &msg);
95
96    static const int64_t kReaperIntervalUs = 1000000ll;
97
98    // We request that the dongle send us a "TEARDOWN" in order to
99    // perform an orderly shutdown. We're willing to wait up to 2 secs
100    // for this message to arrive, after that we'll force a disconnect
101    // instead.
102    static const int64_t kTeardownTriggerTimeouSecs = 2;
103
104    static const int64_t kPlaybackSessionTimeoutSecs = 30;
105
106    static const int64_t kPlaybackSessionTimeoutUs =
107        kPlaybackSessionTimeoutSecs * 1000000ll;
108
109    State mState;
110    sp<ANetworkSession> mNetSession;
111    sp<IRemoteDisplayClient> mClient;
112    struct in_addr mInterfaceAddr;
113    int32_t mSessionID;
114
115    uint32_t mStopReplyID;
116
117    bool mUsingPCMAudio;
118    int32_t mClientSessionID;
119
120    struct ClientInfo {
121        AString mRemoteIP;
122        AString mLocalIP;
123        int32_t mLocalPort;
124        int32_t mPlaybackSessionID;
125        sp<PlaybackSession> mPlaybackSession;
126    };
127    ClientInfo mClientInfo;
128
129    bool mReaperPending;
130
131    int32_t mNextCSeq;
132
133    KeyedVector<ResponseID, HandleRTSPResponseFunc> mResponseHandlers;
134
135#if REQUIRE_HDCP
136    bool mIsHDCP2_0;
137    int32_t mHDCPPort;
138    sp<IHDCP> mHDCP;
139    sp<HDCPObserver> mHDCPObserver;
140
141    bool mHDCPInitializationComplete;
142    bool mSetupTriggerDeferred;
143
144    status_t makeHDCP();
145#endif
146
147    status_t sendM1(int32_t sessionID);
148    status_t sendM3(int32_t sessionID);
149    status_t sendM4(int32_t sessionID);
150    status_t sendM5(int32_t sessionID, bool requestShutdown);
151    status_t sendM16(int32_t sessionID);
152
153    status_t onReceiveM1Response(
154            int32_t sessionID, const sp<ParsedMessage> &msg);
155
156    status_t onReceiveM3Response(
157            int32_t sessionID, const sp<ParsedMessage> &msg);
158
159    status_t onReceiveM4Response(
160            int32_t sessionID, const sp<ParsedMessage> &msg);
161
162    status_t onReceiveM5Response(
163            int32_t sessionID, const sp<ParsedMessage> &msg);
164
165    status_t onReceiveM16Response(
166            int32_t sessionID, const sp<ParsedMessage> &msg);
167
168    void registerResponseHandler(
169            int32_t sessionID, int32_t cseq, HandleRTSPResponseFunc func);
170
171    status_t onReceiveClientData(const sp<AMessage> &msg);
172
173    status_t onOptionsRequest(
174            int32_t sessionID,
175            int32_t cseq,
176            const sp<ParsedMessage> &data);
177
178    status_t onSetupRequest(
179            int32_t sessionID,
180            int32_t cseq,
181            const sp<ParsedMessage> &data);
182
183    status_t onPlayRequest(
184            int32_t sessionID,
185            int32_t cseq,
186            const sp<ParsedMessage> &data);
187
188    status_t onPauseRequest(
189            int32_t sessionID,
190            int32_t cseq,
191            const sp<ParsedMessage> &data);
192
193    status_t onTeardownRequest(
194            int32_t sessionID,
195            int32_t cseq,
196            const sp<ParsedMessage> &data);
197
198    status_t onGetParameterRequest(
199            int32_t sessionID,
200            int32_t cseq,
201            const sp<ParsedMessage> &data);
202
203    status_t onSetParameterRequest(
204            int32_t sessionID,
205            int32_t cseq,
206            const sp<ParsedMessage> &data);
207
208    void sendErrorResponse(
209            int32_t sessionID,
210            const char *errorDetail,
211            int32_t cseq);
212
213    static void AppendCommonResponse(
214            AString *response, int32_t cseq, int32_t playbackSessionID = -1ll);
215
216    void scheduleReaper();
217    void scheduleKeepAlive(int32_t sessionID);
218
219    int32_t makeUniquePlaybackSessionID() const;
220
221    sp<PlaybackSession> findPlaybackSession(
222            const sp<ParsedMessage> &data, int32_t *playbackSessionID) const;
223
224    void finishStop();
225    void disconnectClientAsync();
226    void disconnectClient2();
227    void finishStopAfterDisconnectingClient();
228    void finishStop2();
229
230    DISALLOW_EVIL_CONSTRUCTORS(WifiDisplaySource);
231};
232
233}  // namespace android
234
235#endif  // WIFI_DISPLAY_SOURCE_H_
236