WifiDisplaySource.h revision 16c090555adf9f37bad0f061fd2651b91a34ae41
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    int32_t mClientSessionID;
118
119    struct ClientInfo {
120        AString mRemoteIP;
121        AString mLocalIP;
122        int32_t mLocalPort;
123        int32_t mPlaybackSessionID;
124        sp<PlaybackSession> mPlaybackSession;
125    };
126    ClientInfo mClientInfo;
127
128    bool mReaperPending;
129
130    int32_t mNextCSeq;
131
132    KeyedVector<ResponseID, HandleRTSPResponseFunc> mResponseHandlers;
133
134#if REQUIRE_HDCP
135    bool mIsHDCP2_0;
136    int32_t mHDCPPort;
137    sp<IHDCP> mHDCP;
138    sp<HDCPObserver> mHDCPObserver;
139
140    bool mHDCPInitializationComplete;
141    bool mSetupTriggerDeferred;
142
143    status_t makeHDCP();
144#endif
145
146    status_t sendM1(int32_t sessionID);
147    status_t sendM3(int32_t sessionID);
148    status_t sendM4(int32_t sessionID);
149    status_t sendM5(int32_t sessionID, bool requestShutdown);
150    status_t sendM16(int32_t sessionID);
151
152    status_t onReceiveM1Response(
153            int32_t sessionID, const sp<ParsedMessage> &msg);
154
155    status_t onReceiveM3Response(
156            int32_t sessionID, const sp<ParsedMessage> &msg);
157
158    status_t onReceiveM4Response(
159            int32_t sessionID, const sp<ParsedMessage> &msg);
160
161    status_t onReceiveM5Response(
162            int32_t sessionID, const sp<ParsedMessage> &msg);
163
164    status_t onReceiveM16Response(
165            int32_t sessionID, const sp<ParsedMessage> &msg);
166
167    void registerResponseHandler(
168            int32_t sessionID, int32_t cseq, HandleRTSPResponseFunc func);
169
170    status_t onReceiveClientData(const sp<AMessage> &msg);
171
172    status_t onOptionsRequest(
173            int32_t sessionID,
174            int32_t cseq,
175            const sp<ParsedMessage> &data);
176
177    status_t onSetupRequest(
178            int32_t sessionID,
179            int32_t cseq,
180            const sp<ParsedMessage> &data);
181
182    status_t onPlayRequest(
183            int32_t sessionID,
184            int32_t cseq,
185            const sp<ParsedMessage> &data);
186
187    status_t onPauseRequest(
188            int32_t sessionID,
189            int32_t cseq,
190            const sp<ParsedMessage> &data);
191
192    status_t onTeardownRequest(
193            int32_t sessionID,
194            int32_t cseq,
195            const sp<ParsedMessage> &data);
196
197    status_t onGetParameterRequest(
198            int32_t sessionID,
199            int32_t cseq,
200            const sp<ParsedMessage> &data);
201
202    status_t onSetParameterRequest(
203            int32_t sessionID,
204            int32_t cseq,
205            const sp<ParsedMessage> &data);
206
207    void sendErrorResponse(
208            int32_t sessionID,
209            const char *errorDetail,
210            int32_t cseq);
211
212    static void AppendCommonResponse(
213            AString *response, int32_t cseq, int32_t playbackSessionID = -1ll);
214
215    void scheduleReaper();
216    void scheduleKeepAlive(int32_t sessionID);
217
218    int32_t makeUniquePlaybackSessionID() const;
219
220    sp<PlaybackSession> findPlaybackSession(
221            const sp<ParsedMessage> &data, int32_t *playbackSessionID) const;
222
223    void finishStop();
224    void disconnectClientAsync();
225    void disconnectClient2();
226    void finishStopAfterDisconnectingClient();
227    void finishStop2();
228
229    DISALLOW_EVIL_CONSTRUCTORS(WifiDisplaySource);
230};
231
232}  // namespace android
233
234#endif  // WIFI_DISPLAY_SOURCE_H_
235