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