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