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